pandas KeyError: not in index / None of [Index] (tested)

KeyError: "['x'] not in index" means some of the columns (or row labels) you selected do not exist; "None of [Index([...])] are in the [columns]" means none do; "not found in axis" comes from drop(). We reproduced all three on pandas 2.3.3 and 3.1.0.

1. df[[...]] with a missing column

import pandas as pd

df = pd.DataFrame({"a": [1, 2], "b": [3, 4]})
for cols in (["a", "x"], ["x", "y"]):
    try:
        df[cols]
    except KeyError as e:
        print("KeyError:", e)

print(df[df.columns.intersection(["a", "x"])].columns.tolist())   # keep only existing
print(df.reindex(columns=["a", "x"]).values.tolist())             # missing -> NaN
missing = set(["a", "x"]) - set(df.columns)
print("missing:", missing)

Output with pandas 2.3.3:

KeyError: "['x'] not in index"
KeyError: "None of [Index(['x', 'y'], dtype='object')] are in the [columns]"
['a']
[[1.0, nan], [2.0, nan]]
missing: {'x'}

Output with pandas 3.1.0:

KeyError: "['x'] not in index"
KeyError: "None of [Index(['x', 'y'], dtype='str')] are in the [columns]"
['a']
[[1.0, nan], [2.0, nan]]
missing: {'x'}

Selecting a list of columns raises "['x'] not in index" when some are missing (it lists only the missing ones) and "None of [Index([...])] are in the [columns]" when none exist. The only version difference is the dtype in the message: pandas 3 stores strings as str, pandas 2 as object. Find the missing names with a set difference, then either fix the name (see column exists but KeyError for spaces and BOMs), keep only existing columns with df.columns.intersection(...), or use reindex(columns=...) to get NaN columns instead of an error.

2. drop(): "not found in axis"

import pandas as pd

df = pd.DataFrame({"a": [1, 2], "b": [3, 4]})
try:
    df.drop("x", axis=1)
except KeyError as e:
    print("KeyError:", e)
try:
    df.drop("a")                     # default axis=0 looks in the row index
except KeyError as e:
    print("KeyError:", e)

print(df.drop(columns="a").columns.tolist())
print(df.drop(columns=["a", "x"], errors="ignore").columns.tolist())

Output (identical on pandas 2.3.3 and 3.1.0):

KeyError: "['x'] not found in axis"
KeyError: "['a'] not found in axis"
['b']
['b']

df.drop("a") fails even though a is a column, because drop defaults to axis=0 (row labels). Write df.drop(columns="a"). To drop columns that may not exist, add errors="ignore".

3. Row labels in .loc, and set_index

import pandas as pd

df = pd.DataFrame({"a": [1, 2]}, index=[10, 20])
try:
    df.loc[[10, 30]]
except KeyError as e:
    print("KeyError:", e)
try:
    df.set_index("x")
except KeyError as e:
    print("KeyError:", e)

Output (identical on pandas 2.3.3 and 3.1.0):

KeyError: '[30] not in index'
KeyError: "None of ['x'] are in the columns"

The same "not in index" message appears for row labels in df.loc[[...]]; check with df.index.isin([...]) or select with df[df.index.isin(labels)]. set_index on a missing column says "None of ['x'] are in the columns" (without the Index wrapper).

Related: KeyError: 0 in pandas · Error tokenizing data · SettingWithCopyWarning.

Frequently asked questions

What does KeyError not in index mean in pandas?

One or more of the labels in df[[...]] or df.loc[[...]] are not in the DataFrame. The message lists only the missing ones.

What does 'None of [Index] are in the [columns]' mean?

None of the column names you passed exist. Print list(df.columns) to compare, and watch for spaces or different case.

Why does df.drop('col') say not found in axis?

drop defaults to axis=0, the row index. Use df.drop(columns='col'), and errors='ignore' if it may be missing.

Written with AI assistance. Measured on 2026-10-23 in the python:3-alpine Docker image (Python 3.14) with pandas 2.3.3 and pandas 3.1.0. Each block was run verbatim on both versions and the output pasted unedited; where the versions differ both outputs are shown. PlainHeaders is our extension; Python and pandas are free.