apache/cassandra · error · IOException

Digest mismatch exception

Error message

Digest mismatch exception

What it means

ChecksummedDataInput.checkLimit() throws IOException("Digest mismatch exception") when a requested read of `length` bytes would move the input position past the limit recorded by the current framing (the CRC-protected block set by resetLimit/synchronized reading in hints). Callers such as readFully/read use it to enforce that deserialization stays inside the verified block; exceeding the limit means the encoded length was wrong or the data is corrupt.

Source

Thrown at src/java/org/apache/cassandra/hints/ChecksummedDataInput.java:166

    /**
     * Returns the position in the source file, which is different for getPosition() for compressed/encrypted files
     * and may be imprecise.
     */
    protected long getSourcePosition()
    {
        return bufferOffset;
    }

    public void resetLimit()
    {
        limit = Long.MAX_VALUE;
        limitMark = -1;
    }

    public void checkLimit(int length) throws IOException
    {
        if (getPosition() + length > limit)
            throw new IOException("Digest mismatch exception");
    }

    public long bytesPastLimit()
    {
        assert limitMark != -1;
        return getPosition() - limitMark;
    }

    public boolean checkCrc() throws IOException
    {
        try
        {
            updateCrc();

            // we must disable crc updates in case we rebuffer
            // when called source.readInt()
            crcUpdateDisabled = true;
            return ((int) crc.getValue()) == readInt();

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Delete or move the corrupt hints file(s) out of the hints directory and let the node continue; hints are best-effort deliveries.
  2. Check disks/filesystem for corruption (fsck, SMART) if many hints files are affected.
  3. Verify compression/encryption config for hints matches what was used when the files were written (hints_compression in cassandra.yaml).
  4. Restore affected hints files from a clean backup or let peers' hinted handoff data be re-gedged via repair.

Example fix

// before
input.readFully(buffer, size); // IOException: Digest mismatch exception
// after
try
{
    input.readFully(buffer, size);
}
catch (IOException e)
{
    logger.warn("Corrupt hint block, skipping file", e);
    // abandon current hints file / resync to next descriptor
}
Defensive patterns

Strategy: try-catch

Validate before calling

// before reading, sanity-check the hints file exists and is non-empty
if (!Files.isRegularFile(hintsFile) || Files.size(hintsFile) == 0) skipFile(hintsFile);

Try / catch

try { input.readFully(buf, len); } catch (IOException e) { if (e.getMessage().contains("Digest mismatch")) { abandonCurrentFile(); } else throw e; }

Prevention

When it happens

Trigger: Reading a hints file where a stored hint size or field length exceeds the remaining CRC-checked block: corrupt/truncated file, torn write from hard reboot, or a descriptor/parameters mismatch causing misaligned reads. Raised from readFully/read when their length argument overruns `limit`.

Common situations: Hints files damaged by unclean shutdown (power loss without fsync); copying hints files between nodes or versions; disk corruption; manually editing or truncating hints directories; reading hints written with different compression/encryption parameters than configured.

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/964fa056fc50cf8c. Report an issue: GitHub.