Array Index Out of Bounds —
Why it crashes and how to fix it.
IndexError: list index out of range is one of the most common Python errors. It happens whenever you access an index that doesn't exist — one past the end, a negative index beyond the start, or an off-by-one in a loop. Watch the exact moment the index goes out of range on LearnBug and you'll never write this bug the same way twice.
IndexError: list index out of range
Python raises this error when you try to access an index that doesn't exist in the list. Valid indices for a list of length n are 0 to n-1. Accessing index n or beyond causes the crash.
What causes this error?
Python lists are zero-indexed — a list of 5 elements has valid indices 0, 1, 2, 3, 4. Accessing index 5 or higher crashes immediately. The most common culprit: using len(arr) as an index (it's one too many), or an off-by-one in a loop boundary. Python also raises this error for invalid negative indices below -len(arr).
Why visualization helps
On LearnBug you see the array cells highlighted as your loop variable increments. The moment the index goes out of bounds, the crash point is obvious — you watch the pointer step off the end of the array. The fix becomes clear immediately: check the loop boundary, adjust the condition, or use len(arr) - 1.
Why this error happens
Using len(arr) as the last index
For a list of length 5, valid indices are 0–4. arr[len(arr)] accesses index 5 — one past the end. Always use arr[len(arr) - 1] or just arr[-1] for the last element.
arr = ['a', 'b', 'c', 'd', 'e'] # len = 5
# ❌ Bug: arr[len(arr)] # → IndexError (index 5)
# ✅ Fix: arr[len(arr) - 1] # → 'e' (index 4)
# ✅ Fix: arr[-1] # → 'e' (Pythonic)Off-by-one in a loop — range(len(arr) + 1)
Using range(len(arr) + 1) instead of range(len(arr)) runs the loop one extra time, accessing the index just past the end.
arr = [10, 20, 30]
# ❌ Bug: range(len(arr) + 1) → indices 0,1,2,3 — crashes at 3
for i in range(len(arr) + 1):
print(arr[i])
# ✅ Fix: range(len(arr)) → indices 0,1,2 only
for i in range(len(arr)):
print(arr[i])Accessing index on an empty list
If the list is empty ([]), any index access — including arr[0] — crashes immediately. Always guard with an empty check.
arr = []
# ❌ Bug:
print(arr[0]) # IndexError — list is empty
# ✅ Fix: guard first
if arr:
print(arr[0])Two-pointer loop — right pointer goes past end
In two-pointer problems, if the loop condition allows right to reach len(arr) instead of len(arr) - 1, the next access crashes.
arr = [1, 2, 3, 4]
# ❌ Bug: right can reach len(arr) = 4
right = len(arr) # should be len(arr) - 1
print(arr[right]) # IndexError
# ✅ Fix:
right = len(arr) - 1
print(arr[right]) # → 4Hardcoded index on variable-length input
Writing arr[3] assuming the list always has at least 4 elements. Works on test data but crashes in production when the input is shorter.
# ❌ Bug: assumes arr has at least 4 elements
value = arr[3]
# ✅ Fix: check length first
value = arr[3] if len(arr) > 3 else None
# ✅ Or use .get() on dicts, try/except on lists:
try:
value = arr[3]
except IndexError:
value = NoneQuick checklist when you see IndexError
1. Is your loop using range(len(arr)) not range(len(arr) + 1)?
2. Is your last-element access using arr[-1] or arr[len(arr)-1]?
3. Could the list be empty? Guard with if arr: before accessing.
4. Are any hardcoded indices safe for all possible input lengths?
Frequently asked questions
What is the difference between IndexError and KeyError?
IndexError occurs on sequences (lists, tuples, strings) when you access a position that doesn't exist. KeyError occurs on dictionaries when you access a key that isn't in the dict. Both mean "you asked for something that isn't there" — just on different data structures.
Why does Python allow negative indices?
Python's negative indexing counts from the end: arr[-1] is the last element, arr[-2] is second to last, and so on. It's a convenience feature. However, going too far negative — arr[-6] on a 5-element list — still raises IndexError. Valid negative range is -len(arr) to -1.
How do I safely get an element or a default if index doesn't exist?
Unlike dicts which have .get(key, default), lists don't have a built-in safe access method. Use a conditional: arr[i] if 0 <= i < len(arr) else default. Or use a try/except block. For repeated safe access, write a helper function.
Can this error happen in a while loop?
Yes — and it's often harder to spot. If your while loop condition doesn't correctly bound the index, it can increment past the end. Always verify the exit condition: make sure your loop stops when i < len(arr), not i <= len(arr).
How is this error different from the Java ArrayIndexOutOfBoundsException?
They're the same concept in different languages. Java throws ArrayIndexOutOfBoundsException, Python raises IndexError, C/C++ have undefined behaviour (no error — just memory corruption). Python is safer because it always checks and raises an error rather than silently reading garbage memory.
See the exact index that crashes your code
Paste your code into LearnBug and watch the index pointer step off the array — then fix it live.