apache/druid · error · NotFoundException
Table : not found, is being deleted or update version does…
Error message
Table %s: not found, is being deleted or update version does not match DB version
What it means
alterTable performs a conditional UPDATE guarded by the expected old version (OLD_VERSION_PARAM). If the affected row count is 0, the table either does not exist, was deleted, or its stored version differs from the caller-supplied oldVersion (optimistic concurrency failure). It surfaces as NotFoundException.
Solutions
- Re-read the table via readTable to get the current version, re-apply your change, and retry alterTable with the fresh version.
- Catch NotFoundException and surface a conflict/retry to the user rather than treating it as a missing table blindly.
- Verify the table name/Id is correct and the table wasn't dropped.
- Serialize alterations through the manager's table lock to avoid concurrent version bumps.
Example fix
// before
manager.alterTable(id, staleVersion, spec); // NotFoundException
// after
TableMetadata current = manager.readTable(id);
if (current != null) {
manager.alterTable(id, current.version(), spec); // retry with fresh version
} Defensive patterns
Strategy: retry
Validate before calling
TableMetadata meta = manager.readTable(id);
if (meta == null) {
throw new IllegalStateException("Table does not exist: " + id.sqlName());
}
// use meta.version() as oldVersion Try / catch
try {
manager.alterTable(id, oldVersion, spec);
} catch (NotFoundException e) {
TableMetadata fresh = manager.readTable(id);
if (fresh != null) {
manager.alterTable(id, fresh.version(), rebase(spec, fresh));
}
} Prevention
- Always fetch the current version immediately before alter.
- Rebase your intended change onto the latest table spec before retrying.
- Watch for concurrent editors and use the table lock for multi-step updates.
When it happens
Trigger: Calling alterTable(id, oldVersion, spec) where the row is absent, was removed concurrently, or the DB version no longer equals oldVersion — typically another writer already updated the table.
Common situations: Two editors altering the same table concurrently (lost-update protection kicking in); stale client cache holding an outdated version; the table deleted between read and alter; typo in table name.
Understand the failure class
Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.
Related errors
- argument must be a LONG constant
- Cannot filter datasource
- Cannot handle constant condition
- Cannot handle equality condition involving left-hand…
- Cannot handle non-equijoin condition
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/ed9ca08357d4ef61.
Report an issue: GitHub.
Appendix: source
Thrown at extensions-core/druid-catalog/src/main/java/org/apache/druid/catalog/storage/sql/SQLCatalogManager.java:315
{
@Override
public TableMetadata withHandle(Handle handle) throws NotFoundException
{
final TableId id = table.id();
final TableSpec spec = table.spec();
final long updateTime = System.currentTimeMillis();
final int updateCount = handle
.createStatement(statement(UPDATE_SPEC_STMT))
.bind(SCHEMA_NAME_COL, id.schema())
.bind(TABLE_NAME_COL, id.name())
.bind(TABLE_TYPE_COL, spec.type())
.bind(PROPERTIES_COL, JacksonUtils.toBytes(jsonMapper, spec.properties()))
.bind(COLUMNS_COL, JacksonUtils.toBytes(jsonMapper, spec.columns()))
.bind(UPDATE_TIME_COL, updateTime)
.bind(OLD_VERSION_PARAM, oldVersion)
.execute();
if (updateCount == 0) {
throw new NotFoundException(
"Table %s: not found, is being deleted or update version does not match DB version",
id.sqlName()
);
}
return table.asUpdate(updateTime);
}
}
);
sendUpdate(EventType.UPDATE, revised);
return revised.updateTime();
}
catch (CallbackFailedException e) {
if (e.getCause() instanceof NotFoundException) {
throw (NotFoundException) e.getCause();
}
throw e;
}
}View on GitHub (pinned to 9b90983fd2)