{"record":{"id":"5352dda7b37bfa87","repo":"apache/cassandra","slug":"unable-to-read-partition-key-from-data-file-5352dd","errorCode":null,"errorMessage":"Unable to read partition key from data file","messagePattern":"Unable to read partition key from data file","errorType":"exception","errorClass":"IOError","httpStatus":null,"severity":"critical","filePath":"src/java/org/apache/cassandra/io/sstable/format/bti/BtiTableScrubber.java","lineNumber":173,"sourceCode":"                                           \"Failed to advance to the next index position. Index is corrupted. \" +\n                                           \"Continuing without the index. Last position read is %d.\",\n                                           indexIterator.dataPosition());\n                        indexIterator.close();\n                        indexIterator = null;\n                        currentIndexKey = null;\n                        dataStartFromIndex = -1;\n                        dataSizeFromIndex = -1;\n                    }\n                }\n            }\n\n            String keyName = key == null ? \"(unreadable key)\" : keyString(key);\n            outputHandler.debug(\"partition %s is %s\", keyName, FBUtilities.prettyPrintMemory(dataSizeFromIndex));\n\n            try\n            {\n                if (key == null)\n                    throw new IOError(new IOException(\"Unable to read partition key from data file\", keyReadError));\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                }\n\n                if (indexIterator != null && dataSizeFromIndex > dataFile.length())\n                    throw new IOError(new IOException(\"Impossible partition size (greater than file length): \" + dataSizeFromIndex));\n\n                if (indexIterator != 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            {","sourceCodeStart":155,"sourceCodeEnd":191,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/io/sstable/format/bti/BtiTableScrubber.java#L155-L191","documentation":"Thrown during BTI sstable scrub when the partition key cannot be read from the data file at the position indicated by the index. The scrubber wraps the underlying keyReadError (an IOException from reading the key) in an IOError, since scrubbing cannot proceed for a partition whose key is unreadable. It signals corruption in the data file's key section.","triggerScenarios":"Running `nodetool scrub` on a BTI-format sstable whose data file has corruption in the bytes where a partition key should be, so key deserialization fails and `key == null`.","commonSituations":"Disk corruption or bit rot, truncated data files after a crash, faulty storage hardware, or copying sstables between nodes without corresponding files.","solutions":["Run `nodetool scrub` with --no-validate or restore the sstable from a backup/snapshot","Check dmesg/storage health for underlying disk errors (SMART, RAID checks)","If replication is available, let repair/anti-entropy restore the data and remove the corrupt sstable","Set scrub to keep the bad files (default -n) and examine the corrupt file with sstablemetadata"],"exampleFix":"// before: repeatedly scrubbing a corrupt file\nnodetool scrub keyspace table\n// after: restore from snapshot then repair\nnodetool restore / restore sstable from snapshot; nodetool repair -pr keyspace","handlingStrategy":"try-catch","validationCode":"// verify data file size and readability before scrub\nFile f = new File(dataFile); if (!f.exists() || f.length() == 0) throw new IllegalStateException(\"missing/truncated data file \" + f);","typeGuard":"if (key == null) { outputHandler.warn(\"unreadable partition key, skipping\"); return false; }","tryCatchPattern":"try { scrubInternal(...); } catch (IOError e) { logger.error(\"data file corrupt at partition key; restore or repair\", e.getCause()); }","preventionTips":["Take snapshots before running scrub","Monitor disk health (SMART) to catch corruption early","Always repair after suspect disk events","Copy sstables only as complete component sets"],"tags":["io","corruption","sstable","scrub"],"backgroundTag":"file-read-failed","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"}