apache/cassandra · error · IOException

Invalid checksum: <headerChecksum> != <dataChecksum>

Error message

Invalid checksum: <headerChecksum> != <dataChecksum>

What it means

Each frame stores a CRC32 in its header computed over the compressed payload. reBuffer() recomputes the checksum of the bytes just read and throws this IOException when the stored and computed checksums differ, indicating the frame data was corrupted on disk or in transit.

Source

Thrown at src/java/org/apache/cassandra/io/util/CompressedFrameDataInputPlus.java:82

        int length = compressed.getShort();

        boolean decompress = length >= 0;
        if (!decompress)
            length = -1 - length;

        compressed.clear();
        compressed.limit(length);
        while (compressed.hasRemaining())
        {
            if (channel.read(compressed) < 0)
                throw new EOFException("Incomplete file: header stipulated " + length + " bytes but found only " + compressed.position());
        }
        compressed.flip();
        this.checksum.update(compressed);
        compressed.flip();
        long dataChecksum = checksum.getValue();
        if (headerChecksum != dataChecksum)
            throw new IOException("Invalid checksum: " + headerChecksum + " != " + dataChecksum);

        buffer.clear();
        if (decompress) compressor.uncompress(compressed, buffer);
        else buffer.put(compressed);
        buffer.flip();
    }

    public static <T> T read(File file, IVersionedSerializer<T> serializer) throws IOException
    {
        try (CompressedFrameDataInputPlus in = new CompressedFrameDataInputPlus(DEFAULT_FRAME_SIZE, file.newReadChannel(), ZstdCompressor.getOrCreate(DEFAULT_COMPRESSION_LEVEL), Crc.crc32()))
        {
            int version = in.readUnsignedVInt32();
            return serializer.deserialize(in, version);
        }
    }

    public static <T> T readOne(File file, UnversionedSerializer<T> serializer) throws IOException
    {

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Restore the file from a known-good backup or regenerate it; the frame content is not recoverable via this reader.
  2. Run filesystem/disk health checks (fsck, SMART) on the storage holding the file.
  3. Ensure no process writes to the file while it is being read (check for concurrent writers).
  4. Verify the reader and writer use the same CompressedFrameDataOutputPlus/InputPlus format version.

Example fix

// before
Config cfg = CompressedFrameDataInputPlus.readOne(file, serializer);
// after
Config cfg;
try {
    cfg = CompressedFrameDataInputPlus.readOne(file, serializer);
} catch (IOException e) {
    if (e.getMessage().startsWith("Invalid checksum")) {
        logger.error("Corrupt file {} detected", file, e);
        markCorrupted(file);
        cfg = defaultConfig();
    } else throw e;
}
Defensive patterns

Strategy: try-catch

Try / catch

try { ...read... }
catch (IOException e) {
    if (e.getMessage() != null && e.getMessage().startsWith("Invalid checksum")) handleCorruption(file);
    else throw e;
}

Prevention

When it happens

Trigger: Reading a CompressedFrame file whose payload bytes were altered after write: bit rot, faulty disk, corrupted transfer, or reading bytes from the wrong offset (e.g. file overwritten concurrently or a different file version than the reader expects).

Common situations: Hardware-level corruption on an SSTable-adjacent metadata file; a file written with a different framing/checksum algorithm being read by this reader; concurrent modification of the file while it is being read.

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


AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10). Data as JSON: /api/errors/ac64dc156cc9431e. Report an issue: GitHub.