juicedata/juicefs · error · AclException
Invalid ACL: ACL has " + accessEntries.size() + " access ent
Error message
Invalid ACL: ACL has " + accessEntries.size() + " access entries, which exceeds maximum of " + MAX_ENTRIES + ".
What it means
checkMaxEntries enforces the POSIX ACL size limit: a filesystem ACL may hold at most MAX_ENTRIES entries per scope. The access scope of the supplied ACL exceeds this cap, so the ACL is rejected before being applied. Keeping ACLs bounded prevents unbounded metadata growth in the metadata engine.
Source
Thrown at sdk/java/src/main/java/io/juicefs/utils/AclTransformation.java:201
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) {
throw new AclException("Invalid ACL: ACL has " + defaultEntries.size() + " default entries, which exceeds maximum of " + MAX_ENTRIES + ".");
}
}
private static void calculateMasks(List<AclEntry> aclBuilder, EnumMap<AclEntryScope, AclEntry> providedMask, EnumSet<AclEntryScope> maskDirty, EnumSet<AclEntryScope> scopeDirty) throws AclException {
EnumSet<AclEntryScope> scopeFound = EnumSet.noneOf(AclEntryScope.class);
EnumMap<AclEntryScope, FsAction> unionPerms = Maps.newEnumMap(AclEntryScope.class);
EnumSet<AclEntryScope> maskNeeded = EnumSet.noneOf(AclEntryScope.class);
// Determine which scopes are present, which scopes need a mask, and the
// union of group class permissions in each scope.
for (AclEntry entry : aclBuilder) {
scopeFound.add(entry.getScope());
if (entry.getType() == GROUP || entry.getName() != null) {
FsAction scopeUnionPerms = unionPerms.get(entry.getScope());
if (scopeUnionPerms == null) {
scopeUnionPerms = FsAction.NONE;View on GitHub (pinned to c9a67b23e8)
Solutions
- Reduce the number of access entries — replace individual user entries with group-based entries.
- Use replace instead of merge so the resulting ACL stays under the limit rather than accumulating.
- Split permissions across group memberships managed outside the ACL (e.g. a POSIX group) and grant one group entry.
Example fix
// before mergeAclEntries(path, joinSpec(1000 namedUserEntries)); // exceeds MAX_ENTRIES // after mergeAclEntries(path, "group::r-x,group:team-a:r-x,other::r--"); // one group entry for many users
Defensive patterns
Strategy: validation
Validate before calling
if (accessEntries.size() > MAX_ENTRIES) {
throw new IllegalArgumentException("too many access entries: " + accessEntries.size());
} Try / catch
try {
mergeAclEntries(path, spec);
} catch (AclException e) {
if (e.getMessage().contains("exceeds maximum")) {
spec = compactSpecViaGroups(spec);
replaceAclEntries(path, spec);
} else throw e;
} Prevention
- Count parsed entries and cap the spec before calling the API.
- Prefer group entries over per-user entries for large grants.
- Use replace (not merge) in scripts to avoid unbounded accumulation.
When it happens
Trigger: mergeAclEntries or replaceAclEntries with a spec producing more than MAX_ENTRIES (see AclTransformation.java, typically 32) ACCESS-scope entries, e.g. adding named users/groups past the limit.
Common situations: Bulk-granting access to dozens of users on one path via merge; scripted ACL application over a generated list of principals; migrating ACLs from another system with a higher entry limit.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- Invalid ACL: ACL has " + defaultEntries.size() + " default e
- Invalid ACL: the user, group and other entries are required.
- Invalid default ACL: the user, group and other entries are r
- Invalid ACL: mask is required and cannot be deleted.
- Invalid start or len parameter
AI-assisted analysis of juicedata/juicefs@c9a67b23e8 (2026-09-06).
Data as JSON: /api/errors/7e18829e178f86b0.
Report an issue: GitHub.