quarkusio/quarkus · error · IllegalStateException

PermissionSecurityCheck must be created either for computed

Error message

PermissionSecurityCheck must be created either for computed permissionsor plain permissions, but received both

What it means

The PermissionSecurityCheck constructor throws IllegalStateException if it is given BOTH plain Permission instances and a computed-permissions supplier — exactly one representation must be used. This is an internal/extension programming error during security check wiring, not user configuration.

Source

Thrown at extensions/security/runtime/src/main/java/io/quarkus/security/runtime/interceptor/check/PermissionSecurityCheck.java:32

import io.quarkus.security.spi.runtime.SecurityCheck;
import io.smallrye.mutiny.Uni;

public abstract class PermissionSecurityCheck<T> implements SecurityCheck {

    private static final Uni<Object> SUCCESSFUL_CHECK = Uni.createFrom().nullItem();
    private final T permissions;
    private final Function<Object[], T> computedPermissions;
    private final boolean useComputedPermissions;

    private PermissionSecurityCheck(T permissions, Function<Object[], T> computedPermissions) {
        if (permissions == null) {
            Objects.requireNonNull(computedPermissions);
            this.useComputedPermissions = true;
        } else {
            if (computedPermissions == null) {
                this.useComputedPermissions = false;
            } else {
                throw new IllegalStateException("PermissionSecurityCheck must be created either for computed permissions" +
                        "or plain permissions, but received both");
            }
        }
        this.permissions = permissions;
        this.computedPermissions = computedPermissions;
    }

    private T getPermissions(Object[] parameters) {
        if (useComputedPermissions) {
            return computedPermissions.apply(parameters);
        }
        return permissions;
    }

    @Override
    public void apply(SecurityIdentity identity, Method method, Object[] parameters) {
        checkPermissions(identity, getPermissions(parameters));
    }

View on GitHub (pinned to e1c734241f)

Solutions

  1. Pass either the plain Permission[] or the ComputedPermissions instance, never both; use null for the unused one
  2. If your extension generates both, prefer computed permissions and null the plain array
  3. Update custom security-check recorder code to the current PermissionSecurityCheck constructor contract

Example fix

// before
new PermissionSecurityCheck(new Permission[]{p}, computedPerms); // both -> IllegalStateException
// after
new PermissionSecurityCheck(new Permission[]{p}, null);
Defensive patterns

Strategy: validation

Validate before calling

if (permissions != null && computedPermissions != null) {
  throw new IllegalArgumentException("Pass either plain permissions or computed permissions, not both");
}

Try / catch

try {
  new PermissionSecurityCheck(perms, computedPerms);
} catch (IllegalStateException e) {
  // fix construction: null out one of the two arguments
}

Prevention

When it happens

Trigger: An extension or custom build step constructs new PermissionSecurityCheck(perms, computedPerms) with non-null values for both the permissions and computedPermissions parameters.

Common situations: Custom @SecurityCheckType/permission metadata generators passing both security-check-permissions and computed permissions build items; a Quarkus version change adding the computed-permissions parameter while custom code still passes legacy values.

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/f75e68c58eaee489. Report an issue: GitHub.