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.

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.

Appendix: 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)