apache/cassandra · error · InvalidRequestException
Table with id does not exist
Error message
Table with id {tableId} does not exist What it means
ConsensusRequestRouter.getTableMetadata(TableId) resolves a TableId to TableMetadata; when the id is not in the schema it throws InvalidRequestException. Like the name-based variants, this is expected mainly when a DROP TABLE races in-flight routing for a request that carries only the table's id.
Solutions
- Re-prepare statements / refresh cluster metadata so the client picks up the new TableId after re-creating a table
- Retry with backoff if the drop was intentional; stop sending requests for the dropped table
- Check schema agreement and force a schema reload on the routing node
- If the table should exist, verify it was not accidentally dropped (audit DDL history)
Example fix
// before
PreparedStatement ps = session.prepare("SELECT * FROM ks.tbl WHERE k = ?"); // cached across a DROP/CREATE cycle
// after
// re-prepare on 'table doesn't exist' style errors, e.g. after a DROP+CREATE
session.getCluster().getMetadata().checkSchemaAgreement();
PreparedStatement ps = session.prepare("SELECT * FROM ks.tbl WHERE k = ?"); Defensive patterns
Strategy: try-catch
Validate before calling
TableMetadata tm = session.getCluster().getMetadata().getTable(tableId);
if (tm == null) throw new IllegalArgumentException("Table with id " + tableId + " does not exist"); Try / catch
try { TableMetadata tmd = router.getTableMetadata(cm, tableId); }
catch (InvalidRequestException e) { /* TableId stale: re-resolve from name, re-prepare statements */ } Prevention
- Never cache TableId across DROP/CREATE cycles; resolve from (keyspace, table) each time
- Re-prepare driver statements after table recreation
- Track DDL audit logs to correlate 'table with id' errors with drops
When it happens
Trigger: Routing calls (metadata, isKeyManagedByAccordForReadAndWrite/Write, tableMetadata, tm) receiving a TableId absent from ClusterMetadata/local schema — a dropped table's id still referenced by in-flight requests or cached routing state.
Common situations: DROP TABLE racing Accord traffic; stale prepared statements / cached TableIds in the driver after a table was recreated (new id); version-skew or schema disagreement between nodes.
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
- Keyspace does not exist
- Table . does not exist
- Can't route consensus request to nonexistent CFS
- Cannot set on non-regular table ' .
- Couldn't find table with id
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/69570a901ee4a8fe.
Report an issue: GitHub.
Appendix: source
Thrown at src/java/org/apache/cassandra/service/consensus/migration/ConsensusRequestRouter.java:208
{
TableMetadata metadata = getTableMetadata(cm, tableId);
// Non-distributed tables always take the Paxos path
if (metadata == null)
return pickPaxos();
return routeAndMaybeMigrate(cm, metadata, key, consistencyLevel, requestTime, timeoutNanos, isForWrite);
}
public static TableMetadata getTableMetadata(ClusterMetadata cm, TableId tableId)
{
TableMetadata tm = cm.schema.getTableMetadata(tableId);
if (tm == null)
{
// It's a non-distributed table which is fine, but we want to error if it doesn't exist
// We should never actually reach here unless there is a race with dropping the table
Keyspaces localKeyspaces = Schema.instance.localKeyspaces();
TableMetadata tm2 = localKeyspaces.getTableOrViewNullable(tableId);
if (tm2 == null)
throw new InvalidRequestException("Table with id " + tableId + " does not exist");
return null;
}
return tm;
}
protected ConsensusRoutingDecision routeAndMaybeMigrate(ClusterMetadata cm, @Nonnull TableMetadata tmd, @Nonnull DecoratedKey key, ConsistencyLevel consistencyLevel, Dispatcher.RequestTime requestTime, long timeoutNanos, boolean isForWrite)
{
if (!tmd.params.transactionalMigrationFrom.isMigrating())
return decisionFor(tmd.params.transactionalMode);
TableMigrationState tms = cm.consensusMigrationState.tableStates.get(tmd.id);
if (tms == null)
return decisionFor(tmd.params.transactionalMigrationFrom.from);
Token token = key.getToken();
if (tms.migratedRanges.intersects(token))
return pickMigrated(tms.targetProtocol, IAccordService.NO_HLC);
View on GitHub (pinned to 88fd0f6a0e)