prestodb/presto · error · AccessDeniedException
Cannot delete from table %s%s
Error message
Cannot delete from table %s%s
What it means
Presto throws this AccessDeniedException (PERMISSION_DENIED / ACCESS_DENIED) when the identity is not authorized to delete rows from a table. The connector's AccessControl.checkCanDeleteFromTable implementation denied the DELETE statement via denyDeleteTable. This is an intentional authorization denial for destructive write operations.
Source
Thrown at presto-spi/src/main/java/com/facebook/presto/spi/security/AccessDeniedException.java:237
public static void denyInsertTable(String tableName)
{
denyInsertTable(tableName, null);
}
public static void denyInsertTable(String tableName, String extraInfo)
{
throw new AccessDeniedException(format("Cannot insert into table %s%s", tableName, formatExtraInfo(extraInfo)));
}
public static void denyDeleteTable(String tableName)
{
denyDeleteTable(tableName, null);
}
public static void denyDeleteTable(String tableName, String extraInfo)
{
throw new AccessDeniedException(format("Cannot delete from table %s%s", tableName, formatExtraInfo(extraInfo)));
}
public static void denyTruncateTable(String tableName)
{
denyTruncateTable(tableName, null);
}
public static void denyTruncateTable(String tableName, String extraInfo)
{
throw new AccessDeniedException(format("Cannot truncate table %s%s", tableName, formatExtraInfo(extraInfo)));
}
public static void denyUpdateTableColumns(String tableName, Set<String> updatedColumnNames)
{
denyUpdateTableColumns(tableName, updatedColumnNames, null);
}
public static void denyUpdateTableColumns(String tableName, Set<String> updatedColumnNames, String extraInfo)View on GitHub (pinned to 55bb57d202)
Solutions
- Grant DELETE privilege on the table to the executing principal in the backing authorization system.
- Run cleanup jobs with an account holding delete/write privileges.
- Verify the connector supports DELETE at all (e.g. Hive needs transactional tables); otherwise use the underlying engine's tooling.
- Connector authors: implement checkCanDeleteFromTable with proper authorization rather than unconditional denyDeleteTable.
Example fix
// before (connector)
public boolean checkCanDeleteFromTable(ConnectorIdentity identity, SchemaTableName table, AccessControlContext context) {
denyDeleteTable(table.toString());
}
// after
public boolean checkCanDeleteFromTable(ConnectorIdentity identity, SchemaTableName table, AccessControlContext context) {
if (!isOwner(identity, table)) {
denyDeleteTable(table.toString());
}
return true;
}
Defensive patterns
Strategy: validation
Validate before calling
boolean canDelete = grantsContain(showGrants(table), serviceAccount, "DELETE");
if (!canDelete) {
throw new IllegalStateException("Service account lacks DELETE on " + table);
}
Prevention
- Grant DELETE separately from INSERT where the security model requires it.
- Confirm the connector supports DELETE (transactional tables for Hive) before planning cleanup jobs.
- Run retention jobs with accounts that hold delete privileges.
- Review grants after security audits that may revoke write permissions.
When it happens
Trigger: Executing DELETE FROM t WHERE ... where the connector's checkCanDeleteFromTable(Identity, SchemaTableName) denies the user; some connectors also route through this when the operation is unsupported, denying even for admins.
Common situations: Data-retention/cleanup jobs as underprivileged accounts; connectors that do not support deletes (deny by design); users with INSERT but not DELETE grants.
Related errors
- Cannot set catalog session property:
- Cannot rename a column in table %s%s
- Cannot select from table %s%s
- Cannot insert into table %s%s
- Cannot truncate table %s%s
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/788f5f7da43473af.
Report an issue: GitHub.