juicedata/juicefs · error · AclException
Invalid ACL: multiple entries with same scope, type and name
Error message
Invalid ACL: multiple entries with same scope, type and name.
What it means
AclTransformation.buildAndValidateAcl throws AclException when, after sorting, two ACL entries compare equal (same scope, type and name) — duplicates are not representable in a valid ACL. Called by filterAclEntriesByAclSpec, mergeAclEntries and replaceAclEntries.
Source
Thrown at sdk/java/src/main/java/io/juicefs/utils/AclTransformation.java:169
private AclTransformation() {
}
public static final Comparator<AclEntry> ACL_ENTRY_COMPARATOR = new Comparator<AclEntry>() {
@Override
public int compare(AclEntry entry1, AclEntry entry2) {
return ComparisonChain.start().compare(entry1.getScope(), entry2.getScope(), Ordering.explicit(ACCESS, DEFAULT)).compare(entry1.getType(), entry2.getType(), Ordering.explicit(USER, GROUP, MASK, OTHER)).compare(entry1.getName(), entry2.getName(), Ordering.natural().nullsFirst()).result();
}
};
public static List<AclEntry> buildAndValidateAcl(ArrayList<AclEntry> aclBuilder) throws AclException {
aclBuilder.trimToSize();
Collections.sort(aclBuilder, ACL_ENTRY_COMPARATOR);
// Full iteration to check for duplicates and invalid named entries.
AclEntry prevEntry = null;
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()) {View on GitHub (pinned to c9a67b23e8)
Solutions
- Deduplicate the AclSpec before applying (use a Set keyed by scope/type/name)
- Use replaceAclEntries with a clean full ACL list instead of merging overlapping specs
- Inspect the current ACL (getAclStatus) and remove the duplicate entry
- Fix the tooling/script that generates the spec to avoid repeats
Example fix
// before Set<AclEntry> entries = new HashSet<>(); // preserves last-wins on name // after Map<String, AclEntry> byKey = new LinkedHashMap<>(); spec.forEach(e -> byKey.put(e.getScope()+":"+e.getType()+":"+e.getName(), e)); AclSpec deduped = new AclSpec(new ArrayList<>(byKey.values()));
Defensive patterns
Strategy: validation
Validate before calling
Set<String> seen = new HashSet<>();
for (AclEntry e : aclSpec.getEntries()) {
String k = e.getScope()+":"+e.getType()+":"+e.getName();
if (!seen.add(k)) throw new IllegalArgumentException("Duplicate ACL entry: " + k);
} Type guard
boolean isDuplicateFree(List<AclEntry> entries) {
Set<String> keys = new HashSet<>();
for (AclEntry e : entries)
if (!keys.add(e.getScope()+":"+e.getType()+":"+e.getName())) return false;
return true;
} Try / catch
try {
AclTransformation.mergeAclEntries(...);
} catch (AclException e) {
if (e.getMessage().contains("multiple entries with same scope, type and name")) {
LOG.error("Deduplicate the AclSpec before applying");
} else throw e;
} Prevention
- Build AclSpecs with Sets/Maps keyed by scope:type:name
- Read current ACL and merge carefully to avoid repeats
- Unit-test spec generators for duplicate output
When it happens
Trigger: Submitting an AclSpec (via setAcl/modifyAcl paths) containing two entries that normalize to the same scope+type+name, e.g. duplicate named users or two default user entries.
Common situations: Programmatic AclSpec construction with repeated addEntry for the same principal; merging ACLs where input already contains duplicates; copy-paste of ACL entries in tooling.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Invalid ACL: this entry type must not have a name: " + entry
- No sources given
- Source file " + normalizePath(src) + " is no
- Permission denied: user=" + user + ", access=" + action + ",
- Invalid ACL: the user, group and other entries are required.
AI-assisted analysis of juicedata/juicefs@c9a67b23e8 (2026-09-06).
Data as JSON: /api/errors/7851411367605f2d.
Report an issue: GitHub.