apache/cassandra · warning

Failed to read a hint for

Error message

Failed to read a hint for {}: {} - table with id {} is unknown in file {}

What it means

While deserializing a hint, the target table's id is unknown to this node (UnknownTableException, possibly wrapped as CoordinatorBehindException), meaning the local schema has no table with that id — usually because the table was dropped, or this node's schema is behind/ahead of the sender's. The reader logs this warning naming the endpoint, hostId, tableId and file, then skips the hint's bytes and continues with the next hint.

Solutions

  1. If the table was intentionally dropped, ignore the warning — hints are correctly skipped
  2. Otherwise run schema agreement (nodetool describecluster) and repair schema to sync the missing table
  3. Clear stale hints for dropped tables (nodetool truncatehints) to silence repeated warnings
  4. Check that the hint-sending node is not behind on schema versions

Example fix

// before: hints for a dropped table spamming logs
DROP TABLE was done while hints pending
// after: clear the stale hints
nodetool truncatehints
Defensive patterns

Strategy: validation

Validate before calling

// before replay, check the hint's table still exists locally
TableId id = ...; // from descriptor/context
if (Schema.instance.getTableMetadata(id) == null) {
  logger.warn("Skipping hints for unknown table {}", id);
  return;
}

Try / catch

try {
  hint = Hint.serializer.deserializeIfLive(input, now, size, descriptor.messagingVersion());
} catch (UnknownTableException e) {
  logger.warn("Skipping hint for unknown table {}", e.id);
  input.skipBytes(Ints.checkedCast(size - input.bytesPastLimit()));
  return null; // continue with next hint
}

Prevention

When it happens

Trigger: readHint during replay encounters deserializeIfLive throwing UnknownTableException (or CoordinatorBehindException wrapping one) because descriptor's table no longer exists in local schema; hints written for a DROPped table being replayed.

Common situations: Table dropped while hints for it were queued; schema disagreement where the replaying node hasn't learned about a new table yet; restoring a node from an old snapshot with stale hints files.

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


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

Appendix: source

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

            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;
                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());

View on GitHub (pinned to 88fd0f6a0e)