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
- If the table was intentionally dropped, ignore the warning — hints are correctly skipped
- Otherwise run schema agreement (nodetool describecluster) and repair schema to sync the missing table
- Clear stale hints for dropped tables (nodetool truncatehints) to silence repeated warnings
- 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
- Establish schema agreement before/after DROP TABLE operations
- Run truncatehints after dropping tables to clear queued hints
- Keep schema migrations coordinated cluster-wide
- Run repairs to backfill writes lost to skipped hints
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
- Failed to validate a hint for
- FSReadError
- Unexpected EOF replaying hints
- Unknown table .
- a hints file cannot be configured for both compression and…
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)