apache/cassandra · critical · IOError
Key from data file (%s) does not match key from index file (
Error message
Key from data file (%s) does not match key from index file (%s)
What it means
BigTableScrubber.scrubInternal cross-checks each partition key read from Data.db against the key recorded in Index.db. If they differ, it throws IOError with 'Key from data file (%s) does not match key from index file (%s)' (the data-file key is elided as '_too big_' to avoid huge dumps). This means Data.db and Index.db disagree about partition boundaries — the files are inconsistent.
Source
Thrown at src/java/org/apache/cassandra/io/sstable/format/big/BigTableScrubber.java:158
dataStartFromIndex = currentPartitionPositionFromIndex + 2 + currentIndexKey.remaining();
dataSizeFromIndex = nextPartitionPositionFromIndex - dataStartFromIndex;
}
}
long dataStart = dataFile.getFilePointer();
String keyName = key == null ? "(unreadable key)" : keyString(key);
outputHandler.debug("partition %s is %s", keyName, FBUtilities.prettyPrintMemory(dataSizeFromIndex));
assert currentIndexKey != null || !indexAvailable();
try
{
if (key == null)
throw new IOError(new IOException("Unable to read partition key from data file"));
if (currentIndexKey != null && !key.getKey().equals(currentIndexKey))
{
throw new IOError(new IOException(String.format("Key from data file (%s) does not match key from index file (%s)",
//ByteBufferUtil.bytesToHex(key.getKey()), ByteBufferUtil.bytesToHex(currentIndexKey))));
"_too big_", ByteBufferUtil.bytesToHex(currentIndexKey))));
}
if (indexFile != null && dataSizeFromIndex > dataFile.length())
throw new IOError(new IOException("Impossible partition size (greater than file length): " + dataSizeFromIndex));
if (indexFile != null && dataStart != dataStartFromIndex)
outputHandler.warn("Data file partition position %d differs from index file row position %d", dataStart, dataStartFromIndex);
if (tryAppend(prevKey, key, writer))
prevKey = key;
}
catch (Throwable th)
{
throwIfFatal(th);
outputHandler.warn(th, "Error reading partition %s (stacktrace follows):", keyName);
View on GitHub (pinned to 88fd0f6a0e)
Solutions
- Always copy SSTable generations as a complete component set (Data.db, Index.db, Summary.db, CompressionInfo.db, Statistics.db, TOC.txt) — replace the mixed set with a consistent backup.
- Remove the inconsistent SSTable and run `nodetool repair` to re-replicate correct data.
- Run `nodetool scrub` with appropriate options; if scrub can't reconcile, offline `sstables scrub`/`sstableverify` can help diagnose.
- Check for interrupted compactions on this table and disk errors in system logs.
Example fix
// before: partial copy of sstable components cp *-big-Data.db /backup/ // after: copy all components of each generation cp *-big-*.db /backup/ # includes Index.db, Summary.db, Statistics.db, TOC.txt
Defensive patterns
Strategy: try-catch
Validate before calling
// Java: sanity-check that Data.db and Index.db belong together via generation + creation time
assert dataFile.getPath().replaceAll("-big-Data.db", "")
.equals(indexFile.getPath().replaceAll("-big-Index.db", "")); Try / catch
try {
scrubber.scrub();
} catch (IOError e) {
if (e.getMessage().contains("does not match key from index file")) {
quarantineSstableGeneration(desc); // move all components aside
runRepair();
} else throw e;
} Prevention
- Copy/backup all SSTable components of a generation atomically, never selectively
- Verify sstablemetadata generation/desk ids match across components
- Let compactions finish before taking filesystem-level snapshots
- Use hardlink-based snapshots instead of ad-hoc copies
When it happens
Trigger: During scrub, dataFile key != currentIndexKey: Index.db from a different generation of the file, corrupted key bytes in either file, or a partially overwritten Data.db whose partition boundary drifted from the index.
Common situations: Mixing components from different SSTable generations when copying/backing up files; interrupted compaction or write leaving inconsistent pairs; disk corruption affecting one file but not the other; hand-edited/moved SSTable components.
Understand the failure class
Background: Checksum mismatch errors: "checksum verification failed", "digest mismatch", "expected vs actual checksum" — what they mean and how to fix them — this error's family across 41 libraries.
Related errors
- Failed to read partition index
- The requested position exceeds the index length
- Unable to read partition key from data file
- Impossible partition size (greater than file length):
- First partition does not match index
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/fcc647f7488af48f.
Report an issue: GitHub.