{"record":{"id":"fcc647f7488af48f","repo":"apache/cassandra","slug":"key-from-data-file-s-does-not-match-key-from-in","errorCode":null,"errorMessage":"Key from data file (%s) does not match key from index file (%s)","messagePattern":"Key from data file \\((.+?)\\) does not match key from index file \\((.+?)\\)","errorType":"exception","errorClass":"IOError","httpStatus":null,"severity":"critical","filePath":"src/java/org/apache/cassandra/io/sstable/format/big/BigTableScrubber.java","lineNumber":158,"sourceCode":"                    dataStartFromIndex = currentPartitionPositionFromIndex + 2 + currentIndexKey.remaining();\n                    dataSizeFromIndex = nextPartitionPositionFromIndex - dataStartFromIndex;\n                }\n            }\n\n            long dataStart = dataFile.getFilePointer();\n\n            String keyName = key == null ? \"(unreadable key)\" : keyString(key);\n            outputHandler.debug(\"partition %s is %s\", keyName, FBUtilities.prettyPrintMemory(dataSizeFromIndex));\n            assert currentIndexKey != null || !indexAvailable();\n\n            try\n            {\n                if (key == null)\n                    throw new IOError(new IOException(\"Unable to read partition key from data file\"));\n\n                if (currentIndexKey != null && !key.getKey().equals(currentIndexKey))\n                {\n                    throw new IOError(new IOException(String.format(\"Key from data file (%s) does not match key from index file (%s)\",\n                                                                    //ByteBufferUtil.bytesToHex(key.getKey()), ByteBufferUtil.bytesToHex(currentIndexKey))));\n                                                                    \"_too big_\", ByteBufferUtil.bytesToHex(currentIndexKey))));\n                }\n\n                if (indexFile != null && dataSizeFromIndex > dataFile.length())\n                    throw new IOError(new IOException(\"Impossible partition size (greater than file length): \" + dataSizeFromIndex));\n\n                if (indexFile != null && dataStart != dataStartFromIndex)\n                    outputHandler.warn(\"Data file partition position %d differs from index file row position %d\", dataStart, dataStartFromIndex);\n\n                if (tryAppend(prevKey, key, writer))\n                    prevKey = key;\n            }\n            catch (Throwable th)\n            {\n                throwIfFatal(th);\n                outputHandler.warn(th, \"Error reading partition %s (stacktrace follows):\", keyName);\n","sourceCodeStart":140,"sourceCodeEnd":176,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/io/sstable/format/big/BigTableScrubber.java#L140-L176","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before: partial copy of sstable components\ncp *-big-Data.db /backup/\n// after: copy all components of each generation\ncp *-big-*.db /backup/  # includes Index.db, Summary.db, Statistics.db, TOC.txt","handlingStrategy":"try-catch","validationCode":"// Java: sanity-check that Data.db and Index.db belong together via generation + creation time\nassert dataFile.getPath().replaceAll(\"-big-Data.db\", \"\")\n       .equals(indexFile.getPath().replaceAll(\"-big-Index.db\", \"\"));","typeGuard":null,"tryCatchPattern":"try {\n    scrubber.scrub();\n} catch (IOError e) {\n    if (e.getMessage().contains(\"does not match key from index file\")) {\n        quarantineSstableGeneration(desc); // move all components aside\n        runRepair();\n    } else throw e;\n}","preventionTips":["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"],"tags":["sstable","scrub","index","consistency","corruption"],"backgroundTag":"checksum-mismatch","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}