C# IndexOutOfRangeException — Array or collection index outside valid bounds
IndexOutOfRangeException: index was outside array bounds
Verified against .NET 8 documentation, C# language spec §11.7.10, .NET BCL source code · Updated June 2026
> quick_fix
Check the array or list bounds before accessing by index. Use `array.Length` (for arrays) or `list.Count` (for List<T>) as the upper bound guard. Ensure index >= 0 and index < Length/Count.
// Safe array access
if (index >= 0 && index < array.Length)
{
var item = array[index];
}
// Safe List access
if (index >= 0 && index < list.Count)
{
var item = list[index];
}
// C# 8+ Index type (safe with ^1 for last element)
var last = array[^1]; // equivalent to array[array.Length - 1]
// Foreach when you don't need the index
foreach (var item in array)
{
Console.WriteLine(item);
}What causes this error
IndexOutOfRangeException is thrown when accessing an array (or calling a method on a collection internally backed by an array) with an index that is either negative or greater than or equal to the array's Length. It is the C# equivalent of Java's ArrayIndexOutOfBoundsException.
How to fix it
- 01
step 1
Read the exception message
The message is 'Index was outside the bounds of the array.' The stack trace points to the exact line. Identify the array/list and the index variable used at that line.
- 02
step 2
Check loop boundary conditions
The most common cause: `for (int i = 0; i <= array.Length; i++)` — should be `i < array.Length`. A zero-based array of 5 elements has valid indices 0–4; Length is 5.
- 03
step 3
Validate dynamic indices
When the index comes from user input, configuration, or a calculation, add a bounds check before use. For List<T>, use `list.ElementAtOrDefault(index)` from LINQ to return default(T) instead of throwing.
- 04
step 4
Use C# range and index operators
C# 8+ provides safe index syntax: `array[^1]` for the last element, `array[1..3]` for a range. These still throw if the underlying length is 0, but they eliminate common hardcoded-offset mistakes like `array[array.Length - 1]` on empty arrays.
- 05
step 5
Prefer foreach or LINQ for iteration
If you do not need the numeric index, use `foreach` or LINQ (`array.First()`, `array.Skip(n).FirstOrDefault()`). These eliminate index arithmetic entirely and do not throw IndexOutOfRangeException.
How to verify the fix
- Test with an empty array/list — the fix should handle the zero-length case
- Test with a single-element array — index 0 should work, index 1 should not
- Run all existing unit tests for the affected method
Why IndexOutOfRangeException happens at the runtime level
The .NET CLR performs bounds checking on every array element access as a security guarantee — this prevents buffer overflow vulnerabilities that exist in unmanaged languages. When the JIT-compiled code accesses an element, it compares the index against the array's stored Length header. If the index is negative or >= Length, the CLR throws System.IndexOutOfRangeException. The JIT can elide these checks in provably safe loops (e.g., a for loop with bounds derived from array.Length), but any external or dynamic index always triggers the check.
Common debug mistakes for IndexOutOfRangeException
- Using `i <= array.Length` instead of `i < array.Length` in a for loop
- Accessing `array[array.Length]` — the last valid index is `array.Length - 1`
- Splitting a string and accessing a fixed index without checking the split result count
- Resizing an array (creating a new one) but keeping an old index that referred to the original size
When IndexOutOfRangeException signals a deeper problem
IndexOutOfRangeException in production most often reveals that a data source returned fewer items than the code assumed — a CSV with missing columns, a split result with fewer parts than expected, a database query returning empty results. The fix is not just bounds checking but defensive programming: never assume a data source will return a specific number of elements; always validate the shape of external data before indexing into it.
Editor's take
IndexOutOfRangeException is .NET's bounds-checking mechanism — the CLR verifies every array and list access at runtime and throws this when your index falls outside the valid range. Unlike C/C++ where out-of-bounds access silently corrupts memory, C# fails immediately and loudly. This is actually a feature, not a bug — it prevents an entire class of security vulnerabilities. The most common production scenario is iterating with a manual index counter instead of using `foreach` or LINQ, then getting the boundary condition wrong by one (the classic off-by-one error). In multi-threaded code, this exception often signals a race condition: one thread removes items from a collection while another iterates by index. The fix there isn't bounds-checking — it's using `ConcurrentBag<T>` or adding proper synchronization. Another frequent cause is accessing `DataRow` columns by index instead of by name, where a schema change silently shifts column positions. Senior .NET developers prefer `Span<T>` slicing and LINQ over manual indexing because the API design makes bounds errors structurally impossible. If you're seeing this exception, ask yourself why you're using a raw index at all — there's almost always a higher-level abstraction that eliminates the error class entirely.
By Bikram Nath · Curator · Updated June 2026
Frequently asked questions
What is the difference between IndexOutOfRangeException and ArgumentOutOfRangeException?
IndexOutOfRangeException is thrown specifically by the CLR for array access violations. ArgumentOutOfRangeException is thrown explicitly by code (e.g., List<T> internally throws this, not IndexOutOfRangeException, when you call list[5] on a 3-element list). They behave the same from a developer perspective but come from different sources.
Why does List<T> throw ArgumentOutOfRangeException but arrays throw IndexOutOfRangeException?
Arrays are built into the CLR — bounds checking is done at the hardware/JIT level. List<T> is a managed class that validates its index parameter explicitly and throws ArgumentOutOfRangeException. The distinction is an implementation detail; the fix is the same: validate the index before use.
How do I safely get the last element of an array in C#?
In C# 8+: `array[^1]`. In earlier versions: `array[array.Length - 1]`. Both throw if the array is empty (Length is 0). Always check `array.Length > 0` first, or use `array.LastOrDefault()` from LINQ which returns default(T) for an empty array.