apache/kafka · error · IllegalArgumentException

permissionType must not be ANY

Error message

permissionType must not be ANY

What it means

Thrown by the AccessControlEntry constructor when the supplied AclPermissionType is AclPermissionType.ANY. Like AclOperation.ANY, the ANY permission type is a wildcard permitted only in filters; a stored access control entry must be explicitly ALLOW or DENY. The IllegalArgumentException prevents persisting an ambiguous grant/deny.

Source

Thrown at clients/src/main/java/org/apache/kafka/common/acl/AccessControlEntry.java:47

    final AccessControlEntryData data;

    /**
     * Create an instance of an access control entry with the provided parameters.
     *
     * @param principal non-null principal
     * @param host non-null host
     * @param operation non-null operation, ANY is not an allowed operation
     * @param permissionType non-null permission type, ANY is not an allowed type
     */
    public AccessControlEntry(String principal, String host, AclOperation operation, AclPermissionType permissionType) {
        Objects.requireNonNull(principal);
        Objects.requireNonNull(host);
        Objects.requireNonNull(operation);
        if (operation == AclOperation.ANY)
            throw new IllegalArgumentException("operation must not be ANY");
        Objects.requireNonNull(permissionType);
        if (permissionType == AclPermissionType.ANY)
            throw new IllegalArgumentException("permissionType must not be ANY");
        this.data = new AccessControlEntryData(principal, host, operation, permissionType);
    }

    /**
     * Return the principal for this entry.
     */
    public String principal() {
        return data.principal();
    }

    /**
     * Return the host or `*` for all hosts.
     */
    public String host() {
        return data.host();
    }

    /**

View on GitHub (pinned to c31c9215e1)

Solutions

  1. Set an explicit permission type: AclPermissionType.ALLOW or AclPermissionType.DENY.
  2. If your goal is to search/match existing ACLs, use AccessControlEntryFilter, which accepts ANY.
  3. Fail fast in your own input layer: require allow/deny before reaching the constructor.

Example fix

// before
new AccessControlEntry(principal, host, AclOperation.READ, AclPermissionType.ANY);

// after
new AccessControlEntry(principal, host, AclOperation.READ, AclPermissionType.ALLOW);
Defensive patterns

Strategy: validation

Validate before calling

// AclPermissionType.ANY is a wildcard meaningful only for filters, never for a concrete ACE
AclPermissionType perm = /* from config/request */;
if (perm == null) { /* reject */ }
if (perm == AclPermissionType.ANY) {
    // choose ALLOW or DENY explicitly, or reject the request
}

Type guard

// Narrow an AclPermissionType to the subset legal inside an AccessControlEntry
static boolean isConcreteAclPermissionType(AclPermissionType p) {
    return p != null && p != AclPermissionType.ANY;
}

Try / catch

try {
    AccessControlEntry ace = new AccessControlEntry(principal, host, op, perm);
} catch (IllegalArgumentException e) {
    // message is literally "permissionType must not be ANY"; require caller to supply ALLOW/DENY
}

Prevention

When it happens

Trigger: Constructing `new AccessControlEntry(principal, host, operation, AclPermissionType.ANY)`. Commonly happens when permissionType is left as the enum default, taken from a filter object, or supplied from a form/API caller that did not pick allow vs deny.

Common situations: Defaults in CLI/admin tooling that choose ANY when unspecified; sharing model objects between filter and entry construction; migrating from legacy ACL representations that lacked an allow/deny flag.

Related errors


AI-assisted analysis of apache/kafka@c31c9215e1 (2026-08-03). Data as JSON: /data/errors/6b92bed09ffee7a2.json. Report an issue: GitHub.