juicedata/juicefs · error · AclException

Invalid ACL: this entry type must not have a name: " + entry

Error message

Invalid ACL: this entry type must not have a name: " + entry + ".

What it means

AclValidationException from buildAndValidateAcl: the ACL specification contains a named entry for a type that must be unnamed. Only USER (when not the owner), GROUP, and default entries may carry a name; named OWNER, MASK, or OTHER entries are structurally invalid and rejected during ACL validation before anything reaches JuiceFS.

Source

Thrown at sdk/java/src/main/java/io/juicefs/utils/AclTransformation.java:172

  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()) {
        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.");

View on GitHub (pinned to c9a67b23e8)

Solutions

  1. Remove the name from MASK/OTHER entries before applying the spec
  2. Only set names for USER/GROUP entries (named user/group ACLs)
  3. Fix the ACL string parser so the name field is null for mask/other lines
  4. Validate the AclSpec client-side before calling the transformation API

Example fix

// before
new AclEntry.Builder().setType(AclEntryType.MASK).setName("mask-owner").setPermission(FULL).build()
// after
new AclEntry.Builder().setType(AclEntryType.MASK).setPermission(FULL).build()
Defensive patterns

Strategy: validation

Validate before calling

for (AclEntry e : aclSpec.getEntries()) {
  if (e.getName() != null && (e.getType() == AclEntryType.MASK || e.getType() == AclEntryType.OTHER))
    throw new IllegalArgumentException("MASK/OTHER must not have a name: " + e);
}

Type guard

boolean hasValidEntryTypes(List<AclEntry> entries) {
  return entries.stream().noneMatch(e -> e.getName() != null &&
    (e.getType() == AclEntryType.MASK || e.getType() == AclEntryType.OTHER));
}

Try / catch

try {
  AclTransformation.replaceAclEntries(...);
} catch (AclException e) {
  if (e.getMessage().contains("must not have a name")) {
    LOG.error("Strip names from MASK/OTHER entries: " + e.getMessage());
  } else throw e;
}

Prevention

When it happens

Trigger: Calling any AclTransformation entry point (mergeAclEntries, replaceAclEntries, filterAclEntriesByAclSpec) with a spec containing e.g. type=MASK with name set, or default:other:someName:rwx.

Common situations: Building AclEntries programmatically and accidentally setting the name for MASK/OTHER; parsing ACL strings incorrectly and attaching a name to every entry; migrating ACLs from systems with different entry grammar.

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


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