prestodb/presto · error · AccessDeniedException

Cannot drop a tag from table %s%s

Error message

Cannot drop a tag from table %s%s

What it means

denyDropTag throws AccessDeniedException when the access control layer denies dropping a tag from the given table. Tags are immutable named snapshots in versioned table formats; DROP TAG requires a distinct privilege checked via checkCanDropTag.

Source

Thrown at presto-spi/src/main/java/com/facebook/presto/spi/security/AccessDeniedException.java:457

    public static void denyDropBranch(String tableName)
    {
        denyDropBranch(tableName, null);
    }

    public static void denyDropBranch(String tableName, String extraInfo)
    {
        throw new AccessDeniedException(format("Cannot drop a branch from table %s%s", tableName, formatExtraInfo(extraInfo)));
    }

    public static void denyDropTag(String tableName)
    {
        denyDropTag(tableName, null);
    }

    public static void denyDropTag(String tableName, String extraInfo)
    {
        throw new AccessDeniedException(format("Cannot drop a tag from table %s%s", tableName, formatExtraInfo(extraInfo)));
    }

    public static void denyDropConstraint(String tableName)
    {
        denyDropConstraint(tableName, null);
    }

    public static void denyDropConstraint(String tableName, String extraInfo)
    {
        throw new AccessDeniedException(format("Cannot drop a constraint from table %s%s", tableName, formatExtraInfo(extraInfo)));
    }

    public static void denyAddConstraint(String tableName)
    {
        denyAddConstraint(tableName, null);
    }

    public static void denyAddConstraint(String tableName, String extraInfo)

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Grant DROP TAG privilege to the relevant principal in the access-control configuration
  2. Confirm the cleanup/automation job uses a service account with those privileges
  3. Check the policy engine (Ranger/OPA) actually contains the tag-operation rule and was reloaded after edits
  4. Verify the table name in the policy matches the queried table (catalog.schema.table)

Example fix

// before: OPA policy omits DROP TAG
{"actions": ["SELECT", "CREATE TAG"]}
// after
{"actions": ["SELECT", "CREATE TAG", "DROP TAG"]}
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-check DROP TAG grant
if (!grants(user, catalog, table).contains("DROP TAG")) {
    throw new IllegalStateException("DROP TAG not granted to " + user);
}

Type guard

boolean canDropTag(String user, String table, Map<String, Set<String>> grants) {
    return grants.getOrDefault(user, Set.of()).stream().anyMatch(g -> g.contains("DROP TAG"));
}

Try / catch

try {
    conn.execute("ALTER TABLE t DROP TAG release_1");
} catch (AccessDeniedException e) {
    LOG.warn("DROP TAG denied: %s", e.getMessage());
    throw e;
}

Prevention

When it happens

Trigger: A connector calls checkCanDropTag; the policy rejects and calls denyDropTag(tableName, extraInfo), producing 'Cannot drop a tag from table <table><extraInfo>'.

Common situations: Retiring old release tags on tables where the user lacks drop privileges; automated cleanup jobs running under an unprivileged principal; policy migrations that dropped tag privileges from role definitions.

Related errors


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