{"record":{"id":"17f9b912b0cfea51","repo":"prestodb/presto","slug":"cannot-grant-privilege-s-on-table-s-s","errorCode":null,"errorMessage":"Cannot grant privilege %s on table %s%s","messagePattern":"Cannot grant privilege (.+?) on table (.+?)(.+?)","errorType":"exception","errorClass":"AccessDeniedException","httpStatus":null,"severity":"error","filePath":"presto-spi/src/main/java/com/facebook/presto/spi/security/AccessDeniedException.java","lineNumber":322,"sourceCode":"\n    public static void denySelectView(String viewName)\n    {\n        denySelectView(viewName, null);\n    }\n\n    public static void denySelectView(String viewName, String extraInfo)\n    {\n        throw new AccessDeniedException(format(\"Cannot select from view %s%s\", viewName, formatExtraInfo(extraInfo)));\n    }\n\n    public static void denyGrantTablePrivilege(String privilege, String tableName)\n    {\n        denyGrantTablePrivilege(privilege, tableName, null);\n    }\n\n    public static void denyGrantTablePrivilege(String privilege, String tableName, String extraInfo)\n    {\n        throw new AccessDeniedException(format(\"Cannot grant privilege %s on table %s%s\", privilege, tableName, formatExtraInfo(extraInfo)));\n    }\n\n    public static void denyRevokeTablePrivilege(String privilege, String tableName)\n    {\n        denyRevokeTablePrivilege(privilege, tableName, null);\n    }\n\n    public static void denyRevokeTablePrivilege(String privilege, String tableName, String extraInfo)\n    {\n        throw new AccessDeniedException(format(\"Cannot revoke privilege %s on table %s%s\", privilege, tableName, formatExtraInfo(extraInfo)));\n    }\n\n    public static void denyShowRoles(String catalogName)\n    {\n        throw new AccessDeniedException(format(\"Cannot show roles from catalog %s\", catalogName));\n    }\n\n    public static void denyShowCurrentRoles(String catalogName)","sourceCodeStart":304,"sourceCodeEnd":340,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-spi/src/main/java/com/facebook/presto/spi/security/AccessDeniedException.java#L304-L340","documentation":"Thrown when the identity lacks the GRANT privilege needed to give another principal a privilege on a table. denyGrantTablePrivilege is called from AccessControlManager.checkCanGrantTablePrivilege. With grant options enabled, you additionally need the privilege WITH GRANT OPTION yourself.","triggerScenarios":"GRANT SELECT ON t TO USER u where checkCanGrantTablePrivilege denies the grantor; or GRANT ... WITH GRANT OPTION without holding that option.","commonSituations":"Delegating access management to non-admin users; connectors whose authorizers only let catalog admins grant; confusion between role-based and user-based grant models.","solutions":["Have a catalog admin execute the GRANT","Grant the requester the privilege WITH GRANT OPTION first","Relax access control rules if delegation is intended"],"exampleFix":"// before (bob lacks grant option)\nGRANT SELECT ON sales TO USER carol; -- AccessDeniedException\n// after (as admin)\nGRANT SELECT ON sales TO USER bob WITH GRANT OPTION;\n-- bob now executes: GRANT SELECT ON sales TO USER carol;","handlingStrategy":"validation","validationCode":"// ensure grantor holds the privilege WITH GRANT OPTION before delegating\nboolean canGrant = catalogAdmin.userHasPrivilegeWithGrantOption(grantor, table, privilege);","typeGuard":null,"tryCatchPattern":"try {\n    execute(\"GRANT \" + privilege + \" ON \" + table + \" TO USER \" + grantee);\n} catch (AccessDeniedException e) {\n    throw new SecurityException(\"Escalate to a catalog admin or obtain grant option first\", e);\n}","preventionTips":["Only delegate WITH GRANT OPTION when the recipient truly needs it","Maintain a small admin group for privilege management","Log grant attempts and denials for access reviews"],"tags":["security","authorization","grants","privileges"],"backgroundTag":"access-denied","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"}