{"record":{"id":"c959492b1b37dfd5","repo":"prestodb/presto","slug":"cannot-create-branch-on-table-s-s","errorCode":null,"errorMessage":"Cannot create branch on table %s%s","messagePattern":"Cannot create branch on table (.+?)(.+?)","errorType":"exception","errorClass":"AccessDeniedException","httpStatus":null,"severity":"error","filePath":"presto-spi/src/main/java/com/facebook/presto/spi/security/AccessDeniedException.java","lineNumber":427,"sourceCode":"\n    public static void denyRevokeRoles(Set<String> roles, Set<PrestoPrincipal> grantees)\n    {\n        throw new AccessDeniedException(format(\"Cannot revoke roles %s from %s \", roles, grantees));\n    }\n\n    public static void denySetRole(String role)\n    {\n        throw new AccessDeniedException(format(\"Cannot set role %s\", role));\n    }\n\n    public static void denyCreateBranch(String tableName)\n    {\n        denyCreateBranch(tableName, null);\n    }\n\n    public static void denyCreateBranch(String tableName, String extraInfo)\n    {\n        throw new AccessDeniedException(format(\"Cannot create branch on table %s%s\", tableName, formatExtraInfo(extraInfo)));\n    }\n\n    public static void denyCreateTag(String tableName)\n    {\n        denyCreateTag(tableName, null);\n    }\n\n    public static void denyCreateTag(String tableName, String extraInfo)\n    {\n        throw new AccessDeniedException(format(\"Cannot create tag on table %s%s\", tableName, formatExtraInfo(extraInfo)));\n    }\n\n    public static void denyDropBranch(String tableName)\n    {\n        denyDropBranch(tableName, null);\n    }\n\n    public static void denyDropBranch(String tableName, String extraInfo)","sourceCodeStart":409,"sourceCodeEnd":445,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-spi/src/main/java/com/facebook/presto/spi/security/AccessDeniedException.java#L409-L445","documentation":"denyCreateBranch throws AccessDeniedException when the access control layer denies the user permission to create a branch on the given table. Branching is a table-versioning feature (e.g. Iceberg-style branches); Presto enforces CREATE BRANCH authorization via checkCanCreateBranch before executing the statement.","triggerScenarios":"A connector implementing BranchSupport calls checkCanCreateBranch, whose policy rejects it and calls denyCreateBranch(tableName, extraInfo), producing 'Cannot create branch on table <table><extraInfo>'.","commonSituations":"Users running ALTER TABLE ... CREATE BRANCH (or similar connector syntax) on a table in a catalog whose access control does not grant them table-level CREATE/branch privileges; enterprise policy plugins blocking DDL on production tables.","solutions":["Grant the user/group CREATE BRANCH (or table admin) privilege in the active access control (file-based rules, Ranger/OPA policy)","Confirm the catalog's access-control.properties points at the intended policy file/plugin","Verify the fully qualified table name and catalog in the policy match what the user queried","If branching is not intended for this catalog, use a connector/version without branch support instead of fighting the policy"],"exampleFix":"// before: access-control rules deny all DDL\n{\n  \"catalogs\": [{\"catalog\": \"iceberg\", \"allow\": \"read-only\"}]\n}\n// after: allow branch DDL for data-engineer group\n{\n  \"catalogs\": [{\"catalog\": \"iceberg\", \"allow\": true, \"privileges\": [\"CREATE BRANCH\"]}]\n}","handlingStrategy":"try-catch","validationCode":"// verify CREATE BRANCH privilege via Presto system metadata before DDL\ntry (ResultSet rs = conn.executeQuery(\n        \"SELECT * FROM system.security.table_grants WHERE catalog_name='iceberg' AND table_name='t'\")) {\n    // confirm grantee and privilege include CREATE BRANCH\n}","typeGuard":"boolean hasPrivilege(Set<String> privileges, String needed) {\n    return privileges != null && privileges.contains(needed);\n}","tryCatchPattern":"try {\n    conn.execute(\"ALTER TABLE t CREATE BRANCH b\");\n} catch (AccessDeniedException e) {\n    LOG.warn(\"CREATE BRANCH denied: %s\", e.getMessage());\n    throw e;\n}","preventionTips":["Grant branch privileges to the groups that perform versioning operations","Test new access-control policies against a staging catalog first","Keep catalog/table names in policies fully qualified and consistent","Review access-control plugin reloads after config edits"],"tags":["presto","security","access-denied","branching"],"backgroundTag":"access-denied-authorization","analyzedSha":"55bb57d202de3b926896fa966c2c4a44c779634e","analyzedAt":"2026-09-04T12:50:26.162Z","contentChangedAt":"2026-09-04T12:50:26.162Z","schemaVersion":2},"datasetVersion":"2026-09-11T21:17:09.523Z"}