prestodb/presto · error · SemanticException

MISSING_TABLE

MISSING_TABLE

Error message

Table '%s' does not exist

What it means

Thrown when a REVOKE statement targets a table that cannot be resolved in the metadata after qualification with the session catalog/schema. Presto looks up a TableHandle before applying privileges; if absent, the statement fails fast with a semantic error. No privilege changes occur.

Source

Thrown at presto-main-base/src/main/java/com/facebook/presto/execution/RevokeTask.java:56

import static com.google.common.collect.ImmutableSet.toImmutableSet;
import static com.google.common.util.concurrent.Futures.immediateFuture;

public class RevokeTask
        implements DDLDefinitionTask<Revoke>
{
    @Override
    public String getName()
    {
        return "REVOKE";
    }

    @Override
    public ListenableFuture<?> execute(Revoke 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 revoke permissions
        for (Privilege privilege : privileges) {
            accessControl.checkCanRevokeTablePrivilege(session.getRequiredTransactionId(), session.getIdentity(), session.getAccessControlContext(), privilege, tableName, createPrincipal(statement.getGrantee()), statement.isGrantOptionFor());
        }

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Verify the fully qualified table name (catalog.schema.table) with a SELECT or SHOW TABLES first
  2. Correct typos or stale names in the REVOKE statement
  3. Recreate the table if it was dropped

Example fix

// before
REVOKE SELECT ON hive.default.orers FROM USER alice;
// after
REVOKE SELECT ON hive.default.orders FROM USER alice;
Defensive patterns

Strategy: validation

Validate before calling

QualifiedObjectName name = createQualifiedObjectName(session, statement, table, metadata);
if (metadata.getMetadataResolver(session).getTableHandle(name).isEmpty()) {
    throw new IllegalArgumentException("Table not found: " + name);
}

Try / catch

try {
    return revokeTask.execute(statement, ...);
} catch (SemanticException e) {
    if (e.getCode() == SemanticErrorCode.MISSING_TABLE) {
        // handle absent table: skip or surface a friendly message
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: REVOKE ... ON <qualified table name> where metadata.getMetadataResolver(session).getTableHandle(tableName) returns empty for the resolved QualifiedObjectName.

Common situations: Typo in table/schema/catalog name; table dropped by another process; querying before the connector registered the table; wrong catalog selected.

Related errors


AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04). Data as JSON: /api/errors/7b6177574111d1a9. Report an issue: GitHub.