apache/hadoop · error · InvalidAclOperationException
Default mask is required when a named default acl is present
Error message
Default mask is required when a named default acl is present.
What it means
Thrown by AbfsAclHelper (the engine behind AzureBlobFileSystem.modifyAclEntries) when an ACL modification would leave one or more named default entries (default:user:<name>:..., default:group:<name>:...) without a default mask. POSIX ACL rules require a mask whenever named entries exist, so the helper rejects any spec whose effect is to remove 'default:mask' while containsNamedAce(aclEntries, true) is still true. It surfaces as InvalidAclOperationException, a subclass of AzureBlobFileSystemException (and therefore IOException).
Source
Thrown at hadoop-tools/hadoop-azure/src/main/java/org/apache/hadoop/fs/azurebfs/services/AbfsAclHelper.java:125
} else {
accessAclTouched = true;
}
}
}
if (removeIndicationSet.contains(AbfsHttpConstants.ACCESS_MASK) && containsNamedAce(aclEntries, false)) {
throw new InvalidAclOperationException("Access mask is required when a named access acl is present.");
}
if (accessAclTouched) {
if (removeIndicationSet.contains(AbfsHttpConstants.ACCESS_MASK)) {
aclEntries.remove(AbfsHttpConstants.ACCESS_MASK);
}
recalculateMask(aclEntries, false);
}
if (removeIndicationSet.contains(AbfsHttpConstants.DEFAULT_MASK) && containsNamedAce(aclEntries, true)) {
throw new InvalidAclOperationException("Default mask is required when a named default acl is present.");
}
if (defaultAclTouched) {
if (removeIndicationSet.contains(AbfsHttpConstants.DEFAULT_MASK)) {
aclEntries.remove(AbfsHttpConstants.DEFAULT_MASK);
}
if (removeIndicationSet.contains(AbfsHttpConstants.DEFAULT_USER)) {
aclEntries.put(AbfsHttpConstants.DEFAULT_USER, aclEntries.get(AbfsHttpConstants.ACCESS_USER));
}
if (removeIndicationSet.contains(AbfsHttpConstants.DEFAULT_GROUP)) {
aclEntries.put(AbfsHttpConstants.DEFAULT_GROUP, aclEntries.get(AbfsHttpConstants.ACCESS_GROUP));
}
if (removeIndicationSet.contains(AbfsHttpConstants.DEFAULT_OTHER)) {
aclEntries.put(AbfsHttpConstants.DEFAULT_OTHER, aclEntries.get(AbfsHttpConstants.ACCESS_OTHER));
}
recalculateMask(aclEntries, true);
}
}View on GitHub (pinned to 2add963021)
Solutions
- Remove the remaining named default entries (default:user:<name>, default:group:<name>) in the same modifyAclEntries call so no named default ACE survives without a mask
- Keep the mask: set 'default:mask:<perms>' to a value that covers the named entries instead of removing it
- Replace the entire ACL with fs.setAcl(path, fullSpec) containing a valid, complete default ACL including default:mask
- Read the live ACL first with fs.getAclStatus(path) and compute the resulting spec so the invariant 'named default entries imply default:mask' holds before submitting
Example fix
// before: removes the default mask while a named default ACE remains
// -> InvalidAclOperationException
fs.modifyAclEntries(path, Arrays.asList(
AclEntry.parseAclEntry("default:mask:", true)));
// after: drop the named default entries together with the mask
fs.modifyAclEntries(path, Arrays.asList(
AclEntry.parseAclEntry("default:user:alice:", true),
AclEntry.parseAclEntry("default:mask:", true))); Defensive patterns
Strategy: validation
Validate before calling
boolean keepsNamedDefault(AclStatus st) {
return st.getEntries().stream().anyMatch(e ->
e.getScope() == AclEntryScope.DEFAULT && e.getName() != null);
}
// before removing/emptying default:mask, ensure no named default ACE remains
if (removesDefaultMask(spec) && keepsNamedDefault(fs.getAclStatus(path))) {
spec = stripDefaultMaskRemoval(spec); // or also remove the named default entries
}
fs.modifyAclEntries(path, spec); Try / catch
try {
fs.modifyAclEntries(path, spec);
} catch (InvalidAclOperationException e) {
// spec would leave a named default entry without a default mask;
// recompute the spec from getAclStatus and retry once
} Prevention
- Always read the live ACL with getAclStatus before remove/modify operations
- Never remove default:mask while named default user/group entries exist
- Prefer setAcl with a fully computed, valid spec when restructuring ACLs
When it happens
Trigger: Calling fs.modifyAclEntries(path, aclSpec) with a spec that removes/empties the default mask (e.g. 'default:mask:') while the path still has named default ACEs such as default:user:alice:rwx or default:group:devs:r-x. Internally: removeIndicationSet contains DEFAULT_MASK and containsNamedAce(aclEntries, true) returns true.
Common situations: Porting setfacl cleanup scripts from Linux to ABFS; stripping default masks after deleting most named default entries but leaving one behind; ACL specs copied from local filesystems that assume the mask is silently recalculated; HNS-enabled ADLS Gen2 accounts where modifyAclEntries is reachable.
Related errors
- Cannot remove user, group or other entry from access ACL.
- Invalid <aclSpec> :
- Invalid type of acl in <aclSpec> :
- User {} can not be added
- Group {} can not be added
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/cbcc4b7ba2d972c7.
Report an issue: GitHub.