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

  1. Add the missing base access entry (user::, group::, other::) to the ACL spec before calling the transformation API.
  2. If filtering, verify the AclSpec does not match the required base entries and remove those patterns.
  3. 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

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


AI-assisted analysis of juicedata/juicefs@c9a67b23e8 (2026-09-06). Data as JSON: /api/errors/01f57414351e414a. Report an issue: GitHub.