What is an IndexOutOfRangeException / ArgumentOutOfRangeException and how do I fix it?
Categories:
Understanding and Resolving IndexOutOfRangeException / ArgumentOutOfRangeException in C#

Learn what causes IndexOutOfRangeException and ArgumentOutOfRangeException in C#/.NET, how to diagnose them, and implement robust solutions to prevent these common errors.
In C# and the .NET ecosystem, IndexOutOfRangeException
and ArgumentOutOfRangeException
are two of the most frequently encountered runtime errors. While they both indicate that a value is outside its permissible range, they occur in slightly different contexts. Understanding their nuances is crucial for writing robust and error-free applications. This article will delve into the causes of these exceptions, provide practical examples, and offer strategies for effective prevention and debugging.
What is IndexOutOfRangeException?
The IndexOutOfRangeException
is thrown when an attempt is made to access an element of an array or collection with an index that is outside the bounds of the valid indices. In C#, arrays and most collections are zero-indexed, meaning the first element is at index 0, and the last element is at length - 1
. Trying to access an index less than 0 or greater than or equal to the collection's length will result in this exception.
string[] names = { "Alice", "Bob", "Charlie" };
// Valid access
Console.WriteLine(names[0]); // Output: Alice
Console.WriteLine(names[2]); // Output: Charlie
// Invalid access - IndexOutOfRangeException
// Console.WriteLine(names[3]);
// Console.WriteLine(names[-1]);
Example of valid and invalid array access causing IndexOutOfRangeException.
flowchart TD A[Start Program] --> B{Access Collection Element?} B -->|Yes| C{Is Index < 0 or >= Length?} C -->|Yes| D[Throw IndexOutOfRangeException] C -->|No| E[Access Element Successfully] B -->|No| F[Continue Program]
Flowchart illustrating when an IndexOutOfRangeException occurs.
What is ArgumentOutOfRangeException?
The ArgumentOutOfRangeException
is thrown when the value of an argument is outside the allowable range of values as defined by the invoked method. This exception is more general than IndexOutOfRangeException
and can occur in various scenarios where a method expects an argument to fall within a specific range (e.g., a percentage between 0 and 100, a positive number, a valid enum value, or a specific index for a method like Substring
or Remove
). It's often thrown by methods that perform validation on their input parameters.
string text = "Hello World";
// Valid usage
string sub1 = text.Substring(0, 5); // Output: Hello
Console.WriteLine(sub1);
// Invalid usage - ArgumentOutOfRangeException
// string sub2 = text.Substring(0, 20); // Length is 11, 20 is out of range
// string sub3 = text.Substring(15); // Start index is out of range
List<int> numbers = new List<int> { 1, 2, 3 };
// numbers.RemoveAt(5); // Index 5 is out of range for a list of 3 elements
Examples of ArgumentOutOfRangeException when using string and list methods.
IndexOutOfRangeException
is specifically for array/collection indexing, ArgumentOutOfRangeException
is a broader exception used by methods to indicate that any argument's value is invalid, not just an index. However, methods that take an index as an argument (like Substring
or RemoveAt
) will often throw ArgumentOutOfRangeException
if that index is invalid.Common Causes and Solutions
Both exceptions stem from incorrect assumptions about data ranges or collection sizes. Preventing them involves careful validation and understanding of collection boundaries.
1. Validate Input Parameters
Always validate method arguments, especially if they come from external sources (user input, file reads, network requests). Use if
statements, Guard
clauses, or Debug.Assert
to check for valid ranges before proceeding.
2. Check Collection Bounds
Before accessing an element in an array or list, ensure the index is within 0
and collection.Length - 1
(or collection.Count - 1
). Use for
loops with collection.Length
or collection.Count
as the upper bound, or use foreach
loops when you don't need the index.
3. Use Safe Access Methods
For dictionaries, use TryGetValue
instead of direct indexer access []
to avoid KeyNotFoundException
(which is similar in concept to out-of-range issues for keys). For collections, consider LINQ methods like FirstOrDefault()
or ElementAtOrDefault()
which return a default value instead of throwing an exception if the element is not found or the index is out of bounds.
4. Iterate Safely
When iterating, be mindful of off-by-one errors. A common mistake is using <=
instead of <
when comparing an index to Length
/Count
.
5. Review Loop Conditions
Carefully examine for
and while
loop conditions to ensure they terminate correctly and do not attempt to access elements beyond the collection's boundaries.
// Safe iteration example
List<int> numbers = new List<int> { 10, 20, 30 };
for (int i = 0; i < numbers.Count; i++)
{
Console.WriteLine(numbers[i]);
}
// Using foreach (recommended when index is not needed)
foreach (int num in numbers)
{
Console.WriteLine(num);
}
// Safe access with TryGetValue
Dictionary<string, int> ages = new Dictionary<string, int> { { "Alice", 30 } };
if (ages.TryGetValue("Bob", out int bobAge))
{
Console.WriteLine($"Bob's age: {bobAge}");
}
else
{
Console.WriteLine("Bob not found.");
}
Examples of safe iteration and dictionary access.
try-catch
blocks is possible, it's generally considered bad practice for flow control. Exceptions should be reserved for truly exceptional circumstances. Proactive validation and defensive programming are preferred over reactive exception handling for these types of errors.