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

  1. 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).
  2. Fix nested expressions: for params like "order.customerId", ensure 'order' is a method parameter and the path resolves on the target side.
  3. Align the custom Permission class constructor signature so every params entry has a constructor parameter of the same name.
  4. 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

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


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