apache/cassandra · error · IOException

Digest mismatch exception

Error message

Digest mismatch exception

What it means

HintsReader.computeNextInternal throws IOException("Digest mismatch exception") when input.checkCrc() fails: the per-hint CRC stored alongside the entry does not match the bytes read for the declared size. Since the size itself was non-zero, the CRC was the only way to corroborate it; a mismatch means the entry is corrupt and the hint cannot be safely skipped or returned.

Source

Thrown at src/java/org/apache/cassandra/hints/HintsReader.java:228

        private Hint computeNextInternal() throws IOException
        {
            input.resetCrc();
            input.resetLimit();

            int size = input.readInt();
            if (size == 0)
            {
                // Avoid throwing IOException when a hint file ends with a run of zeros - this
                // can happen when hard-rebooting unresponsive machines.
                if (!verifyAllZeros(input))
                    throw new IOException("Corrupt hint file found");
                throw new EOFException("Unexpected end of file (size == 0)");
            }

            // if we cannot corroborate the size via crc, then we cannot safely skip this hint
            if (!input.checkCrc())
                throw new IOException("Digest mismatch exception");

            return readHint(size);
        }

        private Hint readHint(int size) throws IOException
        {
            applyThrottleRateLimit(size);
            input.limit(size);

            Hint hint;
            try
            {
                hint = Hint.serializer.deserializeIfLive(input, now, size, descriptor.messagingVersion());
                input.checkLimit(0);
            }
            catch (UnknownTableException | CoordinatorBehindException e)
            {
                TableId id = ((UnknownTableException) (e instanceof CoordinatorBehindException ? e.getCause() : e)).id;

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Delete or quarantine the corrupt hints file and restart the node/hint delivery.
  2. Verify disk and filesystem health; repeated corruption warrants hardware checks.
  3. Run repair to cover any hints that were lost and never delivered.
  4. Align Cassandra versions across the cluster to avoid descriptor/entry format mismatch.

Example fix

// before
Hint hint = reader.iterator().next(); // IOException: Digest mismatch exception
// after
try
{
    for (Hint hint : HintsReader.open(file))
        deliver(hint);
}
catch (IOException e)
{
    logger.warn("CRC failure in hints file {}, dropping file", file, e);
    Files.deleteIfExists(file);
}
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-check: skip files that are still being written or implausibly small
if (Files.getLastModifiedTime(file).compareTo(lastStartupTime) > 0 && !isActiveFile(file)) skipFile(file);

Try / catch

try { hint = reader.readHint(size); } catch (IOException e) { if (e.getMessage().contains("Digest mismatch")) dropCorruptFile(); else throw e; }

Prevention

When it happens

Trigger: Reading a hints file where a hint entry's bytes were corrupted (torn write, bit rot, partial overwrite) so the stored CRC no longer matches; also happens when a reader misparses sizes due to version/format mismatch, desynchronizing the stream.

Common situations: Hints files damaged by hard power loss or crash without clean flush; storage corruption; hint files written by an incompatible Cassandra version being read by another; copying files mid-write.

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/391b2934f16fb09b. Report an issue: GitHub.