quarkusio/quarkus · error · java.lang.IllegalArgumentException

Method '%s#%s' parameter '%s' cannot be mapped to a Permissi

Error message

Method '%s#%s' parameter '%s' cannot be mapped to a Permission constructor parameter,
                            because expression '%s' specified in the '@PermissionsAllowed#params' attribute is
                            accessible from method '%s#%s' which is not a public method.

What it means

When validating an @PermissionsAllowed params expression, Quarkus resolves a segment as a method (or field getter) on the outer class and requires that method to be public, since it will be invoked to obtain the Permission constructor argument. If the resolved accessor method is not public, the build fails with this error.

Source

Thrown at extensions/security/deployment/src/main/java/io/quarkus/security/deployment/PermissionSecurityChecks.java:1707

            var paramExpression = nestedParams[nestedParamIdx];
            var outerClass = index.getClassByName(outerType.name());
            if (outerClass == null) {
                throw new IllegalArgumentException("""
                            Method '%s#%s' parameter '%s' cannot be converted to a Permission constructor parameter
                            as required by the '@PermissionsAllowed#params' attribute. Parameter expression references '%s'
                            that has type '%s' which is not a class. Only class methods or fields can be mapped
                            to a Permission constructor parameter.
                        """.formatted(securedMethod.declaringClass().name(), securedMethod.name(),
                        securedMethod.parameterName(methodParamIdx), paramExpression, outerType.name()));
            }

            var method = outerClass.method(paramExpression);
            if (method == null) {
                method = outerClass.method(toFieldGetter(paramExpression));
            }
            if (method != null) {
                if (!Modifier.isPublic(method.flags())) {
                    throw new IllegalArgumentException("""
                            Method '%s#%s' parameter '%s' cannot be mapped to a Permission constructor parameter,
                            because expression '%s' specified in the '@PermissionsAllowed#params' attribute is
                            accessible from method '%s#%s' which is not a public method.
                            """.formatted(securedMethod.declaringClass().name(), securedMethod.name(),
                            securedMethod.parameterName(methodParamIdx), paramExpression, method.declaringClass().name(),
                            method.name()));
                }
                validateNestedParams(nestedParams, nestedParamIdx + 1, method.returnType(), securedMethod, methodParamIdx);
            } else {
                var field = outerClass.field(paramExpression);
                if (field == null) {
                    throw new IllegalArgumentException("""
                            Method '%s#%s' parameter '%s' cannot be mapped to a Permission constructor parameter,
                            because expression '%s' specified in the '@PermissionsAllowed#params' attribute does not
                            match any method or field of the class '%s'.
                            """.formatted(securedMethod.declaringClass().name(), securedMethod.name(),
                            securedMethod.parameterName(methodParamIdx), paramExpression, outerClass.name()));
                }

View on GitHub (pinned to e1c734241f)

Solutions

  1. Make the referenced accessor method public.
  2. Rename the expression to point at a public getter or public field instead.
  3. Expose a public getter that delegates to the non-public method and reference that in params.
  4. Move the check into a custom Permission implementation or @PermissionChecker that can access the non-public member.

Example fix

// before
class Order { String getOwner() { return owner; } } // package-private
@PermissionsAllowed("read:order.owner")

// after
class Order { public String getOwner() { return owner; } }
Defensive patterns

Strategy: validation

Validate before calling

// check before build: every method referenced in @PermissionsAllowed params must be public
if (!java.lang.reflect.Modifier.isPublic(Order.class.getMethod("getOwner").getModifiers())) { /* fix visibility */ }

Prevention

When it happens

Trigger: An @PermissionsAllowed params expression segment matches a non-public method name (or a 'getX'/'isX' getter whose method is package-private/protected/private) on the traversed class.

Common situations: Package-private or protected getters on entities used in expressions; Lombok @Getter with non-default access; methods made non-public during a refactor.

Related errors


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