prestodb/presto · error · SemanticException

MISSING_CATALOG

MISSING_CATALOG

Error message

Catalog '%s' does not exist

What it means

Thrown by DropTableTask.execute when the catalog portion of the DROP TABLE target does not exist. Unlike the table check, this one throws even before consulting schemaExists, and it is a SemanticException raised unconditionally (no IF EXISTS bypass at this level).

Source

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

import static com.google.common.util.concurrent.Futures.immediateFuture;

public class DropTableTask
        implements DDLDefinitionTask<DropTable>
{
    @Override
    public String getName()
    {
        return "DROP TABLE";
    }

    @Override
    public ListenableFuture<?> execute(DropTable statement, TransactionManager transactionManager, Metadata metadata, AccessControl accessControl, Session session, List<Expression> parameters, WarningCollector warningCollector, String query)
    {
        QualifiedObjectName tableName = createQualifiedObjectName(session, statement, statement.getTableName(), metadata);
        MetadataResolver metadataResolver = metadata.getMetadataResolver(session);

        if (!metadataResolver.catalogExists(tableName.getCatalogName())) {
            throw new SemanticException(MISSING_CATALOG, "Catalog '%s' does not exist", tableName.getCatalogName());
        }

        if (!metadataResolver.schemaExists(tableName.getCatalogSchemaName())) {
            throw new SemanticException(MISSING_SCHEMA, statement, "Schema '%s' does not exist", tableName.getSchemaName());
        }

        Optional<TableHandle> tableHandle = metadataResolver.getTableHandle(tableName);
        if (!tableHandle.isPresent()) {
            if (!statement.isExists()) {
                throw new SemanticException(MISSING_TABLE, statement, "Table '%s' does not exist", tableName);
            }
            return immediateFuture(null);
        }

        Optional<MaterializedViewDefinition> optionalMaterializedView = metadataResolver.getMaterializedView(tableName);
        if (optionalMaterializedView.isPresent()) {
            if (!statement.isExists()) {
                throw new SemanticException(NOT_SUPPORTED, statement, "'%s' is a materialized view, not a table. Use DROP MATERIALIZED VIEW to drop.", tableName);

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Run SHOW CATALOGS to see valid catalogs and fix the prefix.
  2. Verify the connector properties file exists on the coordinator (etc/catalog/<name>.properties) and restart if you added it.
  3. Check environment/config templating that generates the qualified table name.

Example fix

// before
DROP TABLE ${catalog}.default.events;
// after
DROP TABLE hive.default.events; -- ensure ${catalog} resolves to a deployed connector
Defensive patterns

Strategy: validation

Validate before calling

// validate catalog before any DROP TABLE
List<String> catalogs = query("SHOW CATALOGS");
if (!catalogs.contains("hive")) {
  throw new IllegalStateException("Catalog 'hive' not deployed on this cluster");
}

Prevention

When it happens

Trigger: metadataResolver.catalogExists(tableName.getCatalogName()) returns false during DROP TABLE processing.

Common situations: Misspelled catalog; connector not configured on the cluster (missing etc/catalog properties file); cluster restart lost a catalog; script templating substituted an empty/wrong catalog variable.

Related errors


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