How to Fix IndexError: tuple index out of range in Python

IndexError: tuple index out of range means you asked for a position the tuple doesn’t have. A tuple of length n has indexes 0 to n - 1 only. Fix it by checking len() first, looping without indexes, or handling empty tuples:

store = ("Austin", "TX", 78701)
store[3]        # IndexError: valid indexes are 0, 1, 2

The tracebacks here are copied from Python 3.12.5, so the arrows under the failing index match what you’ll see.

You’ll see the error itself, off-by-one loops, empty tuples from database queries, *args with too few values, and five fixes, from a length check to star unpacking.

What causes IndexError: tuple index out of range?

Indexes start at 0, so the last valid index is one less than the length. Negative indexes count from the end, down to -len(t):

store = ("Austin", "TX", 78701)
print(store[0], store[2], store[-1], store[-3])
print(store[3])

Output:

Austin 78701 78701 Austin
Traceback (most recent call last):
  File "C:\pyguides\tuple_index.py", line 3, in <module>
    print(store[3])
          ~~~~~^^^
IndexError: tuple index out of range
Command Prompt traceback of Python IndexError tuple index out of range after valid positive and negative indexes
Indexes 0, 2, -1 and -3 print the store fields, then store[3] raises IndexError: tuple index out of range.

Python 3.11+ underlines the exact index that failed. The same rule applies to lists and strings, as explained in fixing IndexError: list index out of range.

Fix off-by-one loops over a tuple

range(len(t) + 1) or <= instead of < goes one step too far. Usually you don’t need the index at all:

prices = (19.99, 5.25, 102.00)

total = 0.0
try:
    for i in range(len(prices) + 1):      # one step too far
        total += prices[i]
except IndexError as err:
    print(f"failed at i={i}: {err}")

total = sum(prices)                         # no index needed at all
print(f"total: ${total:.2f}")
for i, price in enumerate(prices, start=1):
    print(f"item {i}: ${price:.2f}")

Output:

failed at i=3: tuple index out of range
total: $127.24
item 1: $19.99
item 2: $5.25
item 3: $102.00
Command Prompt output of a Python loop failing at i=3 on a three-item tuple, then sum and enumerate without indexing
The loop fails at i=3; sum() gives the $127.24 total and enumerate numbers the items without any index math.

enumerate() gives you a counter and the item together. Other looping patterns are in iterating through tuples in Python.

Why does indexing a function’s result raise this error?

Functions that return search results often return an empty tuple when nothing matches. Indexing [0] on that fails, as with this database lookup:

import sqlite3

db = sqlite3.connect(":memory:")
db.execute("CREATE TABLE customers (id INTEGER, name TEXT, state TEXT)")
db.executemany("INSERT INTO customers VALUES (?, ?, ?)", [(1, "Emily Carter", "TX"), (2, "James Wilson", "CO")])

def find_by_state(state):
    return tuple(db.execute("SELECT name FROM customers WHERE state = ?", (state,)))

print(find_by_state("TX"))
print(find_by_state("FL"))                  # no match -> empty tuple

try:
    first = find_by_state("FL")[0]
except IndexError as err:
    print("IndexError:", err)

rows = find_by_state("FL")
first = rows[0][0] if rows else "no customer in FL"
print(first)

Output:

(('Emily Carter',),)
()
IndexError: tuple index out of range
no customer in FL
Command Prompt output of Python sqlite3 query returning an empty tuple for a state with no customers and the resulting IndexError
Texas returns one customer, Florida returns an empty tuple, and indexing it raises IndexError until the code checks for empty first.

if rows is False for an empty tuple, so test before you index. More empty checks are in checking if a tuple is empty in Python.

Fix IndexError when using *args

*args collects positional arguments into a tuple, so a caller passing too few values triggers the same error inside your function:

def ship(*args):
    print(f"got {len(args)} argument(s): {args}")
    return f"ship to {args[0]}, {args[1]}"

print(ship("Denver", "CO"))
try:
    ship("Denver")
except IndexError as err:
    print("IndexError:", err)

def ship_fixed(city: str, state: str = "TX") -> str:   # named parameters fail clearly
    return f"ship to {city}, {state}"
print(ship_fixed("Denver"))

Output:

got 2 argument(s): ('Denver', 'CO')
ship to Denver, CO
got 1 argument(s): ('Denver',)
IndexError: tuple index out of range
ship to Denver, TX

Named parameters with defaults fail with a clearer message, or not at all. Passing tuples into functions is covered in passing a tuple as an argument to a function.

Five ways to avoid tuple index out of range

Pick the fix that matches what a missing item means in your code:

def get(t: tuple, i: int, default=None):
    """t[i], or default when i is out of range."""
    return t[i] if -len(t) <= i < len(t) else default

store = ("Austin", "TX", 78701)
print(get(store, 1), get(store, 5), get(store, 5, "n/a"), get((), 0, "empty"))

city, *rest = store                 # star unpacking never raises for extra items
print(city, rest)

first, *others = ("Reno",)
print(first, others)

try:
    zip_code = store[3]
except IndexError:
    zip_code = "unknown"
print("zip:", zip_code)

Output:

TX None n/a empty
Austin ['TX', 78701]
Reno []
zip: unknown
Command Prompt output of Python safe tuple access with a get helper, star unpacking and try/except returning defaults
The get helper returns TX, None, n/a and empty; star unpacking splits off the rest; try/except falls back to unknown.

Star unpacking is my favorite when I only need the first item. More unpacking tricks are in unpacking a tuple in Python.

Tuple index fixes compared

SituationFix
Looping over itemsfor item in t or enumerate(t)
Result may be emptyif t: t[0]
Optional positiont[i] if -len(t) <= i < len(t) else default
Only need the first itemfirst, *rest = t
Missing item is raretry: ... except IndexError:
Variable-length *argsNamed parameters with defaults

Other error guides on the site you might need:

Frequently asked questions

What does tuple index out of range mean?

You used an index that’s greater than or equal to the tuple’s length, or below -len(t).

What is the last valid index of a tuple?

len(t) - 1, or simply -1.

Why do I get this error on [0]?

The tuple is empty, often because a function or query found nothing. Check if t: first.

How do I get a tuple item with a default?

Use t[i] if -len(t) <= i < len(t) else default, or wrap the access in try/except IndexError.

Is this error different from list index out of range?

It’s the same IndexError; only the message names the type.

Where is IndexError documented?

See IndexError in the Python docs.