{"record":{"id":"120590f39414a02c","repo":"apache/cassandra","slug":"checksums-do-not-match-for","errorCode":null,"errorMessage":"Checksums do not match for ","messagePattern":"Checksums do not match for ","errorType":"exception","errorClass":"CorruptSSTableException","httpStatus":null,"severity":"critical","filePath":"src/java/org/apache/cassandra/io/sstable/metadata/MetadataSerializer.java","lineNumber":226,"sourceCode":"                components.put(type, type.serializer.deserialize(descriptor.version, dataInputBuffer));\n            }\n        }\n\n        return components;\n    }\n\n    private static void maybeValidateChecksum(CRC32 crc, FileDataInput in, Descriptor descriptor) throws IOException\n    {\n        if (!descriptor.version.hasMetadataChecksum())\n            return;\n\n        int actualChecksum = (int) crc.getValue();\n        int expectedChecksum = in.readInt();\n\n        if (actualChecksum != expectedChecksum)\n        {\n            File file = descriptor.fileFor(Components.STATS);\n            throw new CorruptSSTableException(new IOException(\"Checksums do not match for \" + file), file);\n        }\n    }\n\n    @Override\n    public void mutate(Descriptor descriptor, String description, UnaryOperator<StatsMetadata> transform) throws IOException\n    {\n        if (logger.isTraceEnabled())\n            logger.trace(\"Mutating {} to {}\", descriptor.fileFor(Components.STATS), description);\n\n        mutate(descriptor, transform);\n    }\n\n    @Override\n    public void mutateLevel(Descriptor descriptor, int newLevel) throws IOException\n    {\n        if (logger.isTraceEnabled())\n            logger.trace(\"Mutating {} to level {}\", descriptor.fileFor(Components.STATS), newLevel);\n","sourceCodeStart":208,"sourceCodeEnd":244,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/io/sstable/metadata/MetadataSerializer.java#L208-L244","documentation":"Thrown by MetadataSerializer.maybeValidateChecksum when the CRC32 stored at the end of the Stats component does not match the checksum computed over the statistics metadata just read. Wrapped in a CorruptSSTableException naming the file, it prevents Cassandra from trusting corrupted table statistics.","triggerScenarios":"Reading sstable stats metadata (during sstable open, compaction, or sstablemetadata tool) where the trailing checksum in Statistics.db does not match the computed value — bytes were altered, truncated, or the file is from a mismatched generation.","commonSituations":"Disk corruption, partially copied/incomplete sstable restores, mixing sstable components from different generations, faulty hardware or network storage.","solutions":["Restore the matching Statistics.db from snapshot/backup of the same sstable generation","Remove the corrupt sstable and run `nodetool repair` to re-stream from replicas","Check storage health (SMART, filesystem errors) for the underlying disk","Use `sstablemetadata` on the file to confirm which component is corrupt before deleting"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// pre-validate stats component before opening sstable\ntry (var in = new RandomAccessReader(statsFile)) { /* recompute CRC and compare to trailing int */ }","typeGuard":null,"tryCatchPattern":"try { metadata = serializer.deserialize(descriptor, ...); } catch (CorruptSSTableException e) { logger.error(\"corrupt stats for {}\", e.getFile(), e); quarantineOrRepair(descriptor); }","preventionTips":["Snapshot before touching sstables","Run filesystem checks (fsck) after crashes","Copy sstables as complete verified sets (checksum manifests)","Monitor disk SMART metrics"],"tags":["io","corruption","checksum","sstable"],"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"}