Have you met this while doing something that does not look like reindexing?
dup = pd.DataFrame({'a': [1, 2]}, index=[0, 0])
dup.reindex([0, 1])
ValueError: cannot reindex on an axis with duplicate labels
The index has the label 0 twice. Asking for label 0 has two possible answers, and reindexing has to produce exactly one row per requested label, so Pandas stops.
If the index carries no meaning, throwing it away fixes it outright:
dup.reset_index(drop=True).reindex([0, 1])
a
0 1
1 2
You probably never called reindex
That is what makes this one confusing. Alignment is reindexing underneath, so the error surfaces from ordinary operations: assigning a Series to a column, adding two frames, join, update, where, and comparisons between differently-indexed objects. The traceback mentions reindex because that is the machinery, not because that is what you wrote.
So when it appears, the question is not "where is my reindex" but "which of my objects has a duplicated index".
Finding the duplicates
df.index.duplicated().sum()
df[df.index.duplicated(keep=False)]
The first counts them, the second shows the rows so you can see whether they are genuine duplicates or an index that was never meant to be unique.
Where duplicate labels come from
Overwhelmingly from concat without ignore_index:
pd.concat([pd.read_csv(f) for f in files])
Each file's index starts at zero, so combining ten files gives you ten rows labeled 0. Nothing complains at the time; the error arrives later, from some unrelated-looking line. Adding ignore_index=True renumbers the result and removes the problem at the source:
pd.concat([pd.read_csv(f) for f in files], ignore_index=True)
The other common sources are set_index on a column that is not unique — which is often correct and deliberate — and explode, which repeats the label for each item it unpacks.
When the duplicates are meaningful
Sometimes a repeated index is the point: time series with several readings per timestamp, or a frame indexed by customer with one row per order. In that case do not reset it away. Either operate in a way that does not require alignment, or make the index unique by adding the column that distinguishes the rows:
readings.set_index(['timestamp', 'sensor_id'])
A MultiIndex of two columns is unique where either alone is not, and alignment works again.
The mistakes I see most often
Calling reset_index() without drop=True. That moves the old index into a column, which is right when it holds data and clutter when it does not — and if a column of that name already exists, it raises cannot insert instead.
Fixing it at the point of the error. The duplicate was created earlier, usually at a concat, and fixing it there is a one-word change that prevents the next occurrence too.
Assuming duplicate index means duplicate rows. They are unrelated. drop_duplicates looks at values, not at labels.
Practice
See concat in Pandas for combining frames, reset_index in Pandas for clearing an index, and set_index in Pandas for choosing a better one.