{"record":{"id":"78c6939cbf02c188","repo":"apache/hadoop","slug":"user-is-not-authorized-for-protocol","errorCode":null,"errorMessage":"User {} is not authorized for protocol {}: {}","messagePattern":"User (.+?) is not authorized for protocol (.+?): (.+?)","errorType":"exception","errorClass":"AuthorizationException","httpStatus":null,"severity":"error","filePath":"hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/authorize/ServiceAuthorizationManager.java","lineNumber":124,"sourceCode":"          clientPrincipal =\n              SecurityUtil.getServerPrincipal(clientPrincipal, addr);\n        }\n      } catch (IOException e) {\n        throw (AuthorizationException) new AuthorizationException(\n            \"Can't figure out Kerberos principal name for connection from \"\n                + addr + \" for user=\" + user + \" protocol=\" + protocol)\n            .initCause(e);\n      }\n\n    }\n    if((clientPrincipal != null && !clientPrincipal.equals(user.getUserName())) || \n       acls.length != 2  || !acls[0].isUserAllowed(user) || acls[1].isUserAllowed(user)) {\n      String cause = clientPrincipal != null ?\n          \": this service is only accessible by \" + clientPrincipal :\n          \": denied by configured ACL\";\n      AUDITLOG.warn(AUTHZ_FAILED_FOR + user\n          + \" for protocol=\" + protocol + cause);\n      throw new AuthorizationException(\"User \" + user +\n          \" is not authorized for protocol \" + protocol + cause);\n    }\n    if (addr != null) {\n      String hostAddress = addr.getHostAddress();\n      if (hosts.length != 2 || !hosts[0].includes(hostAddress) ||\n          hosts[1].includes(hostAddress)) {\n        AUDITLOG.warn(AUTHZ_FAILED_FOR + \" for protocol=\" + protocol\n            + \" from host = \" +  hostAddress);\n        throw new AuthorizationException(\"Host \" + hostAddress +\n            \" is not authorized for protocol \" + protocol) ;\n      }\n    }\n    AUDITLOG.info(AUTHZ_SUCCESSFUL_FOR + user + \" for protocol=\"+protocol);\n  }\n\n  public void refresh(Configuration conf,\n                                          PolicyProvider provider) {\n    // Get the system property 'hadoop.policy.file'","sourceCodeStart":106,"sourceCodeEnd":142,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/authorize/ServiceAuthorizationManager.java#L106-L142","documentation":"ServiceAuthorizationManager.authorize throws AuthorizationException when the user fails the protocol ACL check: with Kerberos on, the client principal does not match the protocol's expected service principal (clientPrincipal != user.getUserName()); otherwise the user is not in the allow ACL, is in the deny ACL, or the ACL pair is malformed (acls.length != 2). The suffix says which: 'only accessible by <principal>' or 'denied by configured ACL'.","triggerScenarios":"Security enabled and the connecting service's principal differs from the one configured for the protocol (e.g. wrong principal in the keytab/client config); or the user/group is absent from security.<protocol>.acl and present cases trip acls[0].isUserAllowed(user) false / acls[1].isUserAllowed(user) true.","commonSituations":"Restricted protocol ACLs in hadoop-policy.xml (e.g. security.admin.protocol.acl limited to an admin group) and a normal user invoking an admin operation; cross-realm principal mismatches; stale group mappings after changing the user's groups.","solutions":["If the cause is 'denied by configured ACL': add the user or group to security.<protocol>.acl in hadoop-policy.xml and refresh service ACLs","If the cause is 'only accessible by <principal>': fix the client or server principal (krb5 config, keytab, hadoop.security.authentication settings) so both sides agree","Verify group membership resolution (GroupsMapping/LDAP) if access is granted via a group","Refresh with dfsadmin/rmadmin -refreshServiceAcl after policy edits"],"exampleFix":"<!-- hadoop-policy.xml: before -->\n<property>\n  <name>security.admin.protocol.acl</name>\n  <value>hdfsadmin</value>\n</property>\n\n<!-- after: grant the denied user's group -->\n<property>\n  <name>security.admin.protocol.acl</name>\n  <value>hdfsadmin,ops-admins</value>\n</property>","handlingStrategy":"try-catch","validationCode":"// before a privileged call, check membership in the protocol's allow ACL if you can read it\nAccessControlList acl = parsePolicyAcl(\"security.admin.protocol.acl\");\nif (!acl.isUserAllowed(currentUser)) {\n  throw new AccessDeniedException(\"User \" + currentUser\n      + \" lacks protocol ACL; contact cluster admin\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  proxy.makeAdminCall(...);\n} catch (AuthorizationException e) {\n  if (e.getMessage().contains(\"is not authorized for protocol\")) {\n    // permanent denial: report to caller, do not retry\n    throw new AccessDeniedException(e.getMessage());\n  }\n  throw e;\n}","preventionTips":["Document which protocol ACL each client role requires in hadoop-policy.xml","For group-based ACLs, verify the user's groups resolve as the cluster sees them","Keep Kerberos principals consistent between client config and the protocol's service principal"],"tags":["authorization","acl","rpc","kerberos","hadoop-policy","hadoop","security"],"backgroundTag":"acl-access-denied","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}