apache/hadoop · error · AccessControlException
{}
Error message
{} What it means
denyUserAccess(AuthorizationContext, String errorMessage) is the hook an authorization provider should implement so external enforcers can audit denied requests; the default implementation just rethrows AccessControlException with whatever errorMessage the caller passed. Hitting it means access was denied for the reason given in errorMessage and the configured provider did not override denyUserAccess, so no external audit/notification happened.
Source
Thrown at hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/INodeAttributeProvider.java:446
callerUgi.getShortUserName() + ". Superuser privilege is " +
"required for operation " + authzContext.getOperationName());
}
}
/**
* This method must be called when denying access to users to
* notify the external enforcers.
* This will help the external enforcers to audit the requests
* by users that were denied access.
* @param authzContext an {@link AuthorizationContext} object encapsulating
* the various parameters required to authorize an
* operation.
* @throws AccessControlException
*/
default void denyUserAccess(AuthorizationContext authzContext,
String errorMessage)
throws AccessControlException {
throw new AccessControlException(errorMessage);
}
}
/**
* Initialize the provider. This method is called at NameNode startup
* time.
*/
public abstract void start();
/**
* Shutdown the provider. This method is called at NameNode shutdown time.
*/
public abstract void stop();
@Deprecated
String[] getPathElements(String path) {
path = path.trim();
if (path.charAt(0) != Path.SEPARATOR_CHAR) {View on GitHub (pinned to 2add963021)
Solutions
- Fix the underlying denial — grant the needed ACL/permission or run as an authorized user (see errorMessage for the specific rule)
- Implement denyUserAccess(authzContext, errorMessage) in the provider to forward denials to external enforcers/audit systems
- Use the errorMessage text at the call site to identify which check denied the request when triaging
Example fix
// before: default denyUserAccess -> no audit, just rethrow
// after: audit then deny
class MyEnforcer extends INodeAttributeProvider.AccessControlEnforcer {
@Override public void denyUserAccess(AuthorizationContext ctx,
String errorMessage) throws AccessControlException {
auditLog.warn("denied user={} op={} reason={}",
ctx.getCallerUgi().getShortUserName(),
ctx.getOperationName(), errorMessage);
throw new AccessControlException(errorMessage);
}
} Defensive patterns
Strategy: try-catch
Try / catch
try {
performProtectedOp(ctx);
} catch (AccessControlException e) {
// Denial is expected here; errorMessage already carries the denying reason.
auditDenied(ctx, e.getMessage()); // custom audit, since default provider did none
throw e; // surface as 403/AccessControlException to caller
} Prevention
- Implement denyUserAccess in custom providers so denials reach external enforcers and audit stores
- Log the propagated errorMessage — it identifies the exact denying check
- Alert on denials for service accounts; they usually indicate drift between policy and workload owners
When it happens
Trigger: Any permission-denied code path calls denyUserAccess while the configured INodeAttributeProvider leaves the default in place; the message shown in logs/stack traces is the propagated errorMessage from the denying call site, not generated by this method.
Common situations: Deploying a custom authz plugin for policy enforcement but forgetting the audit hook; debugging denied users and seeing only the generic rethrow with no external enforcement record.
Related errors
- Permission denied: user=%s, path="%s":%s:%s:%s%s
- Access denied for user {}. Superuser privilege is required f
- Permission denied: user=%s, path=\"%s\":%s:%s:%s%s
- {} doesn't support modifyAclEntries
- {} doesn't support removeAclEntries
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/0893a94fd3833163.
Report an issue: GitHub.