prestodb/presto · error · SemanticException
MISSING_TABLE
MISSING_TABLE
Error message
Table '%s' does not exist
What it means
Thrown by GrantTask when GRANT (privilege on a table) is executed against a table name for which metadata.getMetadataResolver(session).getTableHandle(tableName) is empty. Unlike DROP statements there is no IF EXISTS variant, so a missing table always fails with MISSING_TABLE.
Source
Thrown at presto-main-base/src/main/java/com/facebook/presto/execution/GrantTask.java:56
import static com.google.common.collect.ImmutableSet.toImmutableSet;
import static com.google.common.util.concurrent.Futures.immediateFuture;
public class GrantTask
implements DDLDefinitionTask<Grant>
{
@Override
public String getName()
{
return "GRANT";
}
@Override
public ListenableFuture<?> execute(Grant statement, TransactionManager transactionManager, Metadata metadata, AccessControl accessControl, Session session, List<Expression> parameters, WarningCollector warningCollector, String query)
{
QualifiedObjectName tableName = createQualifiedObjectName(session, statement, statement.getTableName(), metadata);
Optional<TableHandle> tableHandle = metadata.getMetadataResolver(session).getTableHandle(tableName);
if (!tableHandle.isPresent()) {
throw new SemanticException(MISSING_TABLE, statement, "Table '%s' does not exist", tableName);
}
Set<Privilege> privileges;
if (statement.getPrivileges().isPresent()) {
privileges = statement.getPrivileges().get().stream()
.map(privilege -> parsePrivilege(statement, privilege))
.collect(toImmutableSet());
}
else {
// All privileges
privileges = EnumSet.allOf(Privilege.class);
}
// verify current identity has permissions to grant permissions
for (Privilege privilege : privileges) {
accessControl.checkCanGrantTablePrivilege(session.getRequiredTransactionId(), session.getIdentity(), session.getAccessControlContext(), privilege, tableName, createPrincipal(statement.getGrantee()), statement.isWithGrantOption());
}
View on GitHub (pinned to 55bb57d202)
Solutions
- Verify the table exists and fix the name (SHOW TABLES, qualify with catalog.schema)
- Create the table before running the GRANT in deployment scripts
- Re-run the grant against the correct catalog/schema
Example fix
// before GRANT SELECT ON orders TO USER bob; -- orders not in current schema // after GRANT SELECT ON sales.orders TO USER bob;
Defensive patterns
Strategy: validation
Validate before calling
-- ensure the table exists before GRANT SELECT * FROM information_schema.tables WHERE table_catalog='sales' AND table_schema='myschema' AND table_name='orders';
Try / catch
try { grantPrivileges(...); } catch (SemanticException e) { if (e.getCode() == SemanticErrorCode.MISSING_TABLE) { /* fail provisioning step with clear message */ } throw e; } Prevention
- Order deployment scripts: CREATE TABLE before GRANT
- Always qualify grants with catalog.schema.table
- Verify names against SHOW TABLES output before running GRANT
When it happens
Trigger: Executing `GRANT SELECT ON table_name TO user` where createQualifiedObjectName resolves the name but no TableHandle exists in the connector.
Common situations: Typo'd table name; granting before table creation in a migration script; wrong current schema so the unqualified name resolves elsewhere; table exists in another catalog.
Related errors
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/7df7cfe07f0647f4.
Report an issue: GitHub.