quarkusio/quarkus · error · java.lang.RuntimeException
Parameter '%s' specified via @PermissionsAllowed#params on s
Error message
Parameter '%s' specified via @PermissionsAllowed#params on secured method '%s'
cannot be matched to any %s '%s' parameter. Please make sure that both
secured method and constructor has formal parameter with name '%1$s'. What it means
When @PermissionsAllowed#params reference secured method parameters that are resolved through a constructor (custom permission) or a @PermissionChecker (Quarkus permission), Quarkus must map each declared param name to a formal parameter of both the secured method and the target (constructor or checker method). If a param cannot be matched, deployment fails with this message listing the unmatched name, the secured method, the match target, and the missing formal parameter name.
Source
Thrown at extensions/security/deployment/src/main/java/io/quarkus/security/deployment/PermissionSecurityChecks.java:1372
this.passActionsToConstructor = constructor.parametersCount() == 2;
}
}
private static void validateParamsDeclaredByUserMatched(SecMethodAndPermCtorIdx[] matches, String[] params,
String[] nestedParamExpressions, MethodInfo securedMethod, MethodInfo constructor,
boolean quarkusPermission, MethodInfo permissionCheckerMethod) {
for (int i = 0; i < params.length; i++) {
int aI = i;
boolean paramMapped = Arrays.stream(matches)
.map(SecMethodAndPermCtorIdx::requiredParamIdx)
.filter(Objects::nonNull)
.anyMatch(mIdx -> mIdx == aI);
if (!paramMapped) {
var paramName = nestedParamExpressions == null || nestedParamExpressions[aI] == null ? params[i]
: params[i] + "." + nestedParamExpressions[aI];
var matchTarget = quarkusPermission ? PermissionSecurityChecksBuilder.toString(permissionCheckerMethod)
: constructor.declaringClass().name().toString();
throw new RuntimeException(
"""
Parameter '%s' specified via @PermissionsAllowed#params on secured method '%s'
cannot be matched to any %s '%s' parameter. Please make sure that both
secured method and constructor has formal parameter with name '%1$s'.
"""
.formatted(paramName, PermissionSecurityChecksBuilder.toString(securedMethod),
quarkusPermission ? "checker" : "constructor", matchTarget));
}
}
if (nestedParamExpressions != null) {
outer: for (int i = 0; i < nestedParamExpressions.length; i++) {
if (nestedParamExpressions[i] != null) {
var nestedParamExp = nestedParamExpressions[i];
for (SecMethodAndPermCtorIdx match : matches) {
if (nestedParamExp.equals(match.nestedParamExpression())) {
continue outer;
}
}View on GitHub (pinned to e1c734241f)
Solutions
- Make the params names match the secured method parameters exactly and ensure the corresponding constructor/checker declares the same formal parameter names (compile with -parameters).
- Fix nested expressions: for params like "order.customerId", ensure 'order' is a method parameter and the path resolves on the target side.
- Align the custom Permission class constructor signature so every params entry has a constructor parameter of the same name.
- Use record-style parameter names or the @ParamName-style conventions supported by Quarkus if names differ.
Example fix
// before
@PermissionsAllowed(value = "get", params = { "custId" })
public Order get(Long customerId, Permission perm) { ... }
// after
@PermissionsAllowed(value = "get", params = { "customerId" })
public Order get(Long customerId, Permission perm) { ... } Defensive patterns
Strategy: validation
Validate before calling
// Compile with parameter names and keep them in sync:
// maven.compiler.parameters=true (pom.xml)
// Verify before build:
// for each @PermissionsAllowed(params={...}) name, the method and the Permission constructor/checker
// must declare a parameter with that exact name. Prevention
- Enable -parameters compilation so formal names survive in bytecode.
- Update @PermissionsAllowed params whenever method/constructor parameter names change.
- Keep nested expressions shallow and matching the target's exposed parameter names.
When it happens
Trigger: @PermissionsAllowed(value="p", params={"customerId"}) where neither the secured method nor the permission's constructor/checker has a parameter formally named 'customerId' (including nested expressions like 'order.customerId' where 'order' exists but the nested path does not map).
Common situations: Renaming a method parameter without updating params (parameter names matter); compiling without -parameters so formal names are lost; mismatch between the custom Permission constructor signature and the annotation params; typos in nested property expressions.
Related errors
- @PermissionsAllowed annotation placed on method '%s' has 'pa
- No '%s' formal parameter name matches '%s' Permission %s par
- Cannot transform exception ${exception}
- Unable to determine if bean '${className}' is available
- HTTP Security policy applied only on Quarkus REST cannot be
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/19fbb797c0c09c16.
Report an issue: GitHub.