{"record":{"id":"2ce6d8fdd510d0b6","repo":"apache/cassandra","slug":"trailing-data-encountered-in-segment-index","errorCode":null,"errorMessage":"Trailing data encountered in segment index ","messagePattern":"Trailing data encountered in segment index ","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/journal/OnDiskIndex.java","lineNumber":149,"sourceCode":"        }\n    }\n\n    void validate() throws IOException\n    {\n        CRC32 crc = Crc.crc32();\n\n        try (DataInputBuffer in = new DataInputBuffer(buffer, true))\n        {\n            int entryCount = in.readInt();\n            updateChecksumInt(crc, entryCount);\n            validateCRC(crc, in.readInt());\n\n            Crc.updateCrc32(crc, buffer, FILE_PREFIX_SIZE, FILE_PREFIX_SIZE + entryCount * ENTRY_SIZE);\n            in.skipBytesFully(entryCount * ENTRY_SIZE);\n            validateCRC(crc, in.readInt());\n\n            if (in.available() != 0)\n                throw new IOException(\"Trailing data encountered in segment index \" + descriptor.fileFor(Component.INDEX));\n        }\n    }\n\n    static <K> void write(\n        NavigableMap<K, long[]> entries, KeySupport<K> keySupport, DataOutputPlus out, int userVersion) throws IOException\n    {\n        CRC32 crc = Crc.crc32();\n\n        int size = entries.values()\n                          .stream()\n                          .mapToInt(offsets -> offsets.length)\n                          .sum();\n        out.writeInt(size);\n        updateChecksumInt(crc, size);\n        out.writeInt((int) crc.getValue());\n\n        for (Map.Entry<K, long[]> entry : entries.entrySet())\n        {","sourceCodeStart":131,"sourceCodeEnd":167,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/journal/OnDiskIndex.java#L131-L167","documentation":"When opening an on-disk segment index, OnDiskIndex.validate reads the declared entry count and verifies the CRC. If bytes remain after the expected content and CRC, the index file is structurally corrupt and an IOException is thrown. This detects truncated-then-appended or wrongly-sized index files.","triggerScenarios":"Opening a segment whose INDEX component contains extra bytes beyond entryCount*ENTRY_SIZE plus prefix and CRC — e.g. corrupted file, wrong file paired with a descriptor, or a partially overwritten index.","commonSituations":"Crash during index write leaving inconsistent size; copying segments incorrectly; disk corruption; manually rebuilding/moving journal files.","solutions":["Delete the corrupted segment index and run journal recovery/reserialization so the index is rebuilt","Restore the segment files from a verified backup","Check disk health (filesystem errors, bad sectors)","Verify segments were copied atomically (no partial files) when moving data between nodes"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// check expected index size = FILE_PREFIX_SIZE + entryCount*ENTRY_SIZE + 4 before opening\nlong expected = readEntryCount(file)*ENTRY_SIZE + FILE_PREFIX_SIZE + 4; if (Files.size(indexFile) != expected) quarantine(file);","typeGuard":null,"tryCatchPattern":"try { OnDiskIndex.open(desc, ...); } catch (IOException e) { if (e.getMessage().contains(\"Trailing data\")) rebuildIndex(desc); else throw e; }","preventionTips":["Copy/backup segments atomically","Run filesystem checks after crashes","Rely on journal reserialization to rebuild indexes","Monitor for partial files after unclean shutdowns"],"tags":["corruption","index","crc","io"],"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"}