prestodb/presto · error · TableNotFoundException
Table not found: ${databaseName}.${tableName}
Error message
Table not found: ${databaseName}.${tableName} What it means
HiveMetastore.getFields is a default interface method that resolves the table then returns its storage descriptor columns. If getTable finds no table it throws TableNotFoundException with the qualified name rather than returning Optional.empty.
Source
Thrown at presto-hive-metastore/src/main/java/com/facebook/presto/hive/metastore/thrift/HiveMetastore.java:179
}
default void setPartitionLeases(MetastoreContext metastoreContext, String databaseName, String tableName, Map<String, String> partitionNameToLocation, Duration leaseDuration)
{
throw new UnsupportedOperationException();
}
default boolean isTableOwner(MetastoreContext metastoreContext, String user, String databaseName, String tableName)
{
// a table can only be owned by a user
Optional<Table> table = getTable(metastoreContext, databaseName, tableName);
return table.isPresent() && user.equals(table.get().getOwner());
}
default Optional<List<FieldSchema>> getFields(MetastoreContext metastoreContext, String databaseName, String tableName)
{
Optional<Table> table = getTable(metastoreContext, databaseName, tableName);
if (!table.isPresent()) {
throw new TableNotFoundException(new SchemaTableName(databaseName, tableName));
}
if (table.get().getSd() == null) {
throw new PrestoException(HIVE_INVALID_METADATA, "Table is missing storage descriptor");
}
return Optional.of(table.get().getSd().getCols());
}
default Optional<PrimaryKeyConstraint<String>> getPrimaryKey(MetastoreContext metastoreContext, String databaseName, String tableName)
{
return Optional.empty();
}
default List<UniqueConstraint<String>> getUniqueConstraints(MetastoreContext metastoreContext, String databaseName, String tableName)
{
return ImmutableList.of();
}View on GitHub (pinned to 55bb57d202)
Solutions
- Confirm the table exists via SHOW TABLES / SHOW CREATE TABLE before calling metadata APIs.
- Refresh Presto metadata caches if the table was recently created or dropped (or restart/reconnect).
- Check the catalog and schema qualifiers in the query.
- Verify metastore permissions for the executing principal.
Example fix
// before
ColumnHandle ch = metadata.getFields(session, new SchemaTableName("web", "logs")); // logs absent
// after
if (metadata.getTableHandle(session, new SchemaTableName("web", "logs")) != null) {
metadata.getFields(session, new SchemaTableName("web", "logs"));
} Defensive patterns
Strategy: validation
Validate before calling
// caller-side existence check
boolean present = metadata.getTableHandle(session, qualifiedTableName) != null;
if (!present) { throw new UserInputError("table not found: " + qualifiedTableName); } Try / catch
try {
columns = metadata.getColumnHandles(session, tableHandle);
} catch (TableNotFoundException e) {
LOG.error("getFields failed: %s", e.getMessage());
// refresh metadata cache or re-resolve the table handle
} Prevention
- Refresh or invalidate metadata caches after DDL
- Resolve table handles via metadata APIs rather than cached names
- Use qualified names and verify against system.metadata.tables
- Check metastore visibility permissions for the principal
When it happens
Trigger: Calling getFields (used by metadata/preview paths) for a databaseName.tableName absent from the metastore.
Common situations: Stale cached metadata pointing at a dropped table; typos in generated queries; querying a table in a different catalog; permission-filtered visibility in secured metastores.
Related errors
- HIVE_INVALID_METADATA
- HIVE_INVALID_METADATA
- Table not found: ${databaseName}.${tableName}
- Table not found: ${databaseName}.${tableName}
- Table not found
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/15b29747a2382f81.
Report an issue: GitHub.