juicedata/juicefs · error · AclException
Invalid ACL: the user, group and other entries are required.
Error message
Invalid ACL: the user, group and other entries are required.
What it means
buildAndValidateAcl in AclTransformation.java enforces POSIX ACL invariants before any ACL modification (filter, merge, replace). Every ACL must contain base ACCESS entries of type USER, GROUP and OTHER; binary search over the sorted access entries shows one of these three required entries is missing. This mirrors Hadoop's AclTransformation, from which this utility was ported.
Source
Thrown at sdk/java/src/main/java/io/juicefs/utils/AclTransformation.java:185
for (AclEntry entry : aclBuilder) {
if (prevEntry != null && ACL_ENTRY_COMPARATOR.compare(prevEntry, entry) == 0) {
throw new AclException("Invalid ACL: multiple entries with same scope, type and name.");
}
if (entry.getName() != null && (entry.getType() == MASK || entry.getType() == OTHER)) {
throw new AclException("Invalid ACL: this entry type must not have a name: " + entry + ".");
}
prevEntry = entry;
}
ScopedAclEntries scopedEntries = new ScopedAclEntries(aclBuilder);
checkMaxEntries(scopedEntries);
// Search for the required base access entries. If there is a default ACL,
// then do the same check on the default entries.
for (AclEntryType type : EnumSet.of(USER, GROUP, OTHER)) {
AclEntry accessEntryKey = new AclEntry.Builder().setScope(ACCESS).setType(type).build();
if (Collections.binarySearch(scopedEntries.getAccessEntries(), accessEntryKey, ACL_ENTRY_COMPARATOR) < 0) {
throw new AclException("Invalid ACL: the user, group and other entries are required.");
}
if (!scopedEntries.getDefaultEntries().isEmpty()) {
AclEntry defaultEntryKey = new AclEntry.Builder().setScope(DEFAULT).setType(type).build();
if (Collections.binarySearch(scopedEntries.getDefaultEntries(), defaultEntryKey, ACL_ENTRY_COMPARATOR) < 0) {
throw new AclException("Invalid default ACL: the user, group and other entries are required.");
}
}
}
return Collections.unmodifiableList(aclBuilder);
}
private static void checkMaxEntries(ScopedAclEntries scopedEntries) throws AclException {
List<AclEntry> accessEntries = scopedEntries.getAccessEntries();
List<AclEntry> defaultEntries = scopedEntries.getDefaultEntries();
if (accessEntries.size() > MAX_ENTRIES) {
throw new AclException("Invalid ACL: ACL has " + accessEntries.size() + " access entries, which exceeds maximum of " + MAX_ENTRIES + ".");
}
if (defaultEntries.size() > MAX_ENTRIES) {View on GitHub (pinned to c9a67b23e8)
Solutions
- Add the missing base access entry (user::, group::, other::) to the ACL spec before calling the transformation API.
- If filtering, verify the AclSpec does not match the required base entries and remove those patterns.
- When replacing an ACL, include all three base entries in the replacement spec.
Example fix
// before replaceAclEntries(path, "user:alice:rwx,user:bob:r-x"); // after replaceAclEntries(path, "user::rwx,user:alice:rwx,user:bob:r-x,group::r-x,other::r--");
Defensive patterns
Strategy: validation
Validate before calling
def has_base_access_entries(entries):
types = {e.getType() for e in entries if e.getScope() == AclEntryScope.ACCESS}
return {AclEntryType.USER, AclEntryType.GROUP, AclEntryType.OTHER} <= types Try / catch
try {
replaceAclEntries(path, spec);
} catch (AclException e) {
if (e.getMessage().contains("user, group and other entries are required")) {
spec = addBaseEntries(spec); // append user::, group::, other:: and retry
replaceAclEntries(path, spec);
} else throw e;
} Prevention
- Always start ACL specs from a full base trio (user::, group::, other::).
- Never include user::/group::/other:: patterns in filter specs.
- Unit-test ACL builders to assert the three base access entries exist.
When it happens
Trigger: Calling filterAclEntriesByAclSpec, mergeAclEntries or replaceAclEntries with an ACL spec/list that removes or omits one of the required ACCESS entries: user, group, or other (scope=ACCESS).
Common situations: Building an ACL string that starts with named users/groups only (e.g. 'user:bob:rwx'); filtering out the 'other' entry by mistake; parsing a spec like 'group::rwx,user:alice:r--' with no user::/group::/other:: base entries.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- Invalid default ACL: the user, group and other entries are r
- No sources given
- Source file " + normalizePath(src) + " is no
- Invalid ACL: multiple entries with same scope, type and name
- Invalid ACL: this entry type must not have a name: " + entry
AI-assisted analysis of juicedata/juicefs@c9a67b23e8 (2026-09-06).
Data as JSON: /api/errors/01f57414351e414a.
Report an issue: GitHub.