prestodb/presto · error · PrestoException

NOT_SUPPORTED

NOT_SUPPORTED

Error message

Cannot delete from non-managed Hive table

What it means

truncateUnpartitionedTable implements DELETE FROM by recursively deleting the table's data files. This is only safe for MANAGED_TABLE (and MATERIALIZED_VIEW) types; for external or other table types Presto refuses with a PrestoException(NOT_SUPPORTED) because deleting files would destroy data it does not own.

Source

Thrown at presto-hive-metastore/src/main/java/com/facebook/presto/hive/metastore/SemiTransactionalHiveMetastore.java:607

                new MetastoreContext(
                        session.getIdentity(),
                        session.getQueryId(),
                        session.getClientInfo(),
                        session.getClientTags(),
                        session.getSource(),
                        getMetastoreHeaders(session),
                        isUserDefinedTypeEncodingEnabled(session),
                        columnConverterProvider,
                        session.getWarningCollector(),
                        session.getRuntimeStats()),
                databaseName,
                tableName);
        SchemaTableName schemaTableName = new SchemaTableName(databaseName, tableName);
        if (!table.isPresent()) {
            throw new TableNotFoundException(schemaTableName);
        }
        if (!table.get().getTableType().equals(MANAGED_TABLE) && !table.get().getTableType().equals(MATERIALIZED_VIEW)) {
            throw new PrestoException(NOT_SUPPORTED, "Cannot delete from non-managed Hive table");
        }
        if (!table.get().getPartitionColumns().isEmpty()) {
            throw new IllegalArgumentException("Table is partitioned");
        }

        Path path = new Path(table.get().getStorage().getLocation());
        HdfsContext context = new HdfsContext(session, databaseName, tableName, table.get().getStorage().getLocation(), false);
        setExclusive((delegate, hdfsEnvironment) -> {
            RecursiveDeleteResult recursiveDeleteResult = recursiveDeleteFiles(hdfsEnvironment, context, path, ImmutableSet.of(""), false);
            if (!recursiveDeleteResult.getNotDeletedEligibleItems().isEmpty()) {
                throw new PrestoException(HIVE_FILESYSTEM_ERROR, format(
                        "Error deleting from unpartitioned table %s. These items can not be deleted: %s",
                        schemaTableName,
                        recursiveDeleteResult.getNotDeletedEligibleItems()));
            }
            return EMPTY_HIVE_COMMIT_HANDLE;
        });
    }

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Recreate the table as a managed table (without EXTERNAL) if deletion of data is intended
  2. Delete rows with a WHERE-based delete or rebuild the table via CTAS filtered to the desired rows
  3. Manually remove/replace the underlying files and refresh, accepting external-table semantics
  4. Use a different connector/storage that supports DELETE on external data

Example fix

// before
CREATE EXTERNAL TABLE t (...) LOCATION 's3://bucket/t/';
DELETE FROM t; -- NOT_SUPPORTED
// after
CREATE TABLE t (...) LOCATION 's3://bucket/t/'; -- managed
DELETE FROM t;
Defensive patterns

Strategy: validation

Validate before calling

Optional<Table> t = metastore.getTable(metastoreContext, db, tbl);
if (t.isPresent() && !t.get().getTableType().equals(MANAGED_TABLE)
        && !t.get().getTableType().equals(MATERIALIZED_VIEW)) {
    throw new IllegalStateException("Refusing DELETE on non-managed table " + db + "." + tbl);
}

Type guard

boolean isDeletable(Table t) {
    return t.getTableType().equals(MANAGED_TABLE) || t.getTableType().equals(MATERIALIZED_VIEW);
}

Try / catch

try {
    metastore.truncateUnpartitionedTable(session, db, tbl);
} catch (PrestoException e) {
    if (e.getErrorCode() == NOT_SUPPORTED.toErrorCode()) {
        // fall back to CTAS-rebuild or reject the delete request
    } else throw e;
}

Prevention

When it happens

Trigger: Running DELETE FROM <external/non-managed table> (without a WHERE clause that can be handled another way) on a Hive table whose TableType is not MANAGED_TABLE or MATERIALIZED_VIEW.

Common situations: Pointing a Hive connector at external tables on S3/HDFS and attempting a full-table DELETE; config mistakes where tables expected to be managed were created as EXTERNAL; deletion jobs that assume managed storage.

Understand the failure class

Background: Presto NOT_SUPPORTED error: what "not supported" means and how to fix it — this error's family across 3 libraries.

Related errors


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