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 only
accessible from field '%s#%s' which is not a public field. Please declare a getter method. What it means
When an @PermissionsAllowed params expression segment resolves to a field (no matching method/getter exists), Quarkus requires that field be public because it will be read reflectively to build the Permission argument. Non-public fields trigger this build-time error with a suggestion to declare a getter method.
Source
Thrown at extensions/security/deployment/src/main/java/io/quarkus/security/deployment/PermissionSecurityChecks.java:1727
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()));
}
if (!Modifier.isPublic(field.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 only
accessible from field '%s#%s' which is not a public field. Please declare a getter method.
""".formatted(securedMethod.declaringClass().name(), securedMethod.name(),
securedMethod.parameterName(methodParamIdx), paramExpression, field.declaringClass().name(),
field.name()));
}
validateNestedParams(nestedParams, nestedParamIdx + 1, field.type(), securedMethod, methodParamIdx);
}
}
private Expr generateNestedParam(String[] nestedParams, int nestedParamIdx, Expr outer,
BlockCreator bc, Type outerType) {
if (nestedParamIdx == nestedParams.length) {
return outer;
}
// param name or getter nameView on GitHub (pinned to e1c734241f)
Solutions
- Declare a public getter for the field and reference the getter-style name in the params expression.
- Make the field public (less desirable, but allowed).
- Rename the params expression to match the existing public accessor name.
- Compute the value in a custom Permission or @PermissionChecker rather than navigating the field.
Example fix
// before
class Order { private String owner; }
@PermissionsAllowed(value="read", params="order.owner")
// after
class Order { private String owner; public String getOwner() { return owner; } }
@PermissionsAllowed(value="read", params="order.owner") // resolved via public getter Defensive patterns
Strategy: validation
Validate before calling
// ensure a public field or public getter exists for each params segment
boolean ok = java.lang.reflect.Modifier.isPublic(Order.class.getField("owner").getModifiers()); Prevention
- Follow the JavaBean convention: private field + public getter
- Prefer getters over fields in params expressions
- Run a reflection-based unit test validating @PermissionsAllowed expressions
When it happens
Trigger: An expression segment matches a private/package-private/protected field of the traversed class and no public getter method with the same name (or getX/isX form) exists.
Common situations: Entities with private fields and non-standard getter names; expressions written against field names when only differently-named getters exist; records/components whose accessors don't follow the resolved naming convention.
Related errors
- Method '%s#%s' parameter '%s' cannot be mapped to a Permissi
- Invalid @PermissionsAllowed value '%s': %s
- Method '%s' was annotated with '@PermissionsAllowed', but no
- Class '%s' was annotated with '@PermissionsAllowed', but no
- @PermissionAllowed instance that accepts method arguments mu
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/d98a35473e9098b1.
Report an issue: GitHub.