apache/cassandra · warning

Failed to read a hint for {}: {} - digest mismatch for hint

Error message

Failed to read a hint for {}: {} - digest mismatch for hint at position {} in file {}

What it means

Each hint entry in a hints file is protected by a CRC. After deserializing a hint, the input's checkCrc() verifies the stored digest; on mismatch the hint is discarded: this warning logs the endpoint, hostId, byte position and file, and readHint returns null so the corrupted entry is skipped while replay continues. This protects against bit rot or partial writes corrupting a single record.

Source

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

            }
            catch (UnknownTableException | CoordinatorBehindException e)
            {
                TableId id = ((UnknownTableException) (e instanceof CoordinatorBehindException ? e.getCause() : e)).id;
                logger.warn("Failed to read a hint for {}: {} - table with id {} is unknown in file {}",
                            StorageService.instance.getEndpointForHostId(descriptor.hostId),
                            descriptor.hostId,
                            id,
                            descriptor.fileName());
                input.skipBytes(Ints.checkedCast(size - input.bytesPastLimit()));

                hint = null; // set the return value to null and let following code to update/check the CRC
            }

            if (input.checkCrc())
                return hint;

            // log a warning and skip the corrupted entry
            logger.warn("Failed to read a hint for {}: {} - digest mismatch for hint at position {} in file {}",
                        StorageService.instance.getEndpointForHostId(descriptor.hostId),
                        descriptor.hostId,
                        input.getPosition() - size - 4,
                        descriptor.fileName());
            return null;
        }
    }

    /**
     * A verbatim iterator that simply returns the underlying ByteBuffers.
     */
    final class BuffersIterator extends AbstractIterator<ByteBuffer>
    {
        private final InputPosition offset;
        private final long now = currentTimeMillis();

        BuffersIterator(InputPosition offset)
        {

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Check the disk/filesystem health on the hints volume (dmesg, smartctl, fsck)
  2. Accept the loss of the single corrupted hint and run a repair on the affected ranges to backfill missed writes
  3. If corruption is widespread, move the corrupt hints files aside and let new ones be created
  4. Ensure clean shutdown procedures to avoid torn writes
Defensive patterns

Strategy: try-catch

Validate before calling

// detect corruption early: verify file CRC headers after unclean shutdown
// and monitor the hints directory for files changing unexpectedly

Try / catch

if (!input.checkCrc()) {
  logger.warn("CRC mismatch for hint at {} in {}", position, file);
  return null; // skip corrupted entry, continue replay
}

Prevention

When it happens

Trigger: checkCrc() returns false for an entry in the hints file — corrupted bytes at position (input.getPosition() - size - 4), typically from disk corruption, torn writes after a crash, or manual file tampering.

Common situations: Failing disks or filesystem corruption; power loss causing torn writes; copying hints files between nodes incorrectly.

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/92a9a7b6588ff5d8. Report an issue: GitHub.