apache/hadoop · error · AuthorizationException

User {} is not authorized for protocol {}: {}

Error message

User {} is not authorized for protocol {}: {}

What it means

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'.

Source

Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/authorize/ServiceAuthorizationManager.java:124

          clientPrincipal =
              SecurityUtil.getServerPrincipal(clientPrincipal, addr);
        }
      } catch (IOException e) {
        throw (AuthorizationException) new AuthorizationException(
            "Can't figure out Kerberos principal name for connection from "
                + addr + " for user=" + user + " protocol=" + protocol)
            .initCause(e);
      }

    }
    if((clientPrincipal != null && !clientPrincipal.equals(user.getUserName())) || 
       acls.length != 2  || !acls[0].isUserAllowed(user) || acls[1].isUserAllowed(user)) {
      String cause = clientPrincipal != null ?
          ": this service is only accessible by " + clientPrincipal :
          ": denied by configured ACL";
      AUDITLOG.warn(AUTHZ_FAILED_FOR + user
          + " for protocol=" + protocol + cause);
      throw new AuthorizationException("User " + user +
          " is not authorized for protocol " + protocol + cause);
    }
    if (addr != null) {
      String hostAddress = addr.getHostAddress();
      if (hosts.length != 2 || !hosts[0].includes(hostAddress) ||
          hosts[1].includes(hostAddress)) {
        AUDITLOG.warn(AUTHZ_FAILED_FOR + " for protocol=" + protocol
            + " from host = " +  hostAddress);
        throw new AuthorizationException("Host " + hostAddress +
            " is not authorized for protocol " + protocol) ;
      }
    }
    AUDITLOG.info(AUTHZ_SUCCESSFUL_FOR + user + " for protocol="+protocol);
  }

  public void refresh(Configuration conf,
                                          PolicyProvider provider) {
    // Get the system property 'hadoop.policy.file'

View on GitHub (pinned to 2add963021)

Solutions

  1. 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
  2. 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
  3. Verify group membership resolution (GroupsMapping/LDAP) if access is granted via a group
  4. Refresh with dfsadmin/rmadmin -refreshServiceAcl after policy edits

Example fix

<!-- hadoop-policy.xml: before -->
<property>
  <name>security.admin.protocol.acl</name>
  <value>hdfsadmin</value>
</property>

<!-- after: grant the denied user's group -->
<property>
  <name>security.admin.protocol.acl</name>
  <value>hdfsadmin,ops-admins</value>
</property>
Defensive patterns

Strategy: try-catch

Validate before calling

// before a privileged call, check membership in the protocol's allow ACL if you can read it
AccessControlList acl = parsePolicyAcl("security.admin.protocol.acl");
if (!acl.isUserAllowed(currentUser)) {
  throw new AccessDeniedException("User " + currentUser
      + " lacks protocol ACL; contact cluster admin");
}

Try / catch

try {
  proxy.makeAdminCall(...);
} catch (AuthorizationException e) {
  if (e.getMessage().contains("is not authorized for protocol")) {
    // permanent denial: report to caller, do not retry
    throw new AccessDeniedException(e.getMessage());
  }
  throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22). Data as JSON: /api/errors/78c6939cbf02c188. Report an issue: GitHub.