quarkusio/quarkus · error · java.lang.RuntimeException

Found @PermissionChecker annotation instances that authorize

Error message

Found @PermissionChecker annotation instances that authorize the '%s' permissions, however
                            no @PermissionsAllowed annotation instance requires these permissions
                            

What it means

One or more @PermissionChecker methods were registered, but no method in the application requires the permissions they authorize via @PermissionsAllowed. Unused permission checkers indicate a wiring mistake (or dead code) and are rejected at build time; this variant fires when more than one checker is unmatched.

Source

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

                            var constructor = clazz.constructors().get(0);
                            // first constructor parameter must be permission name
                            if (constructor.parametersCount() == 0 || !STRING.equals(constructor.parameterType(0).name())) {
                                throw new RuntimeException(
                                        String.format("Permission constructor '%s' first argument must be '%s'",
                                                clazz.name().toString(), String.class.getName()));
                            }
                            // rest of validation needs to be done for computed classes only and per each secured method
                            // therefore we do it later

                            // cache validation result
                            classSignatureToConstructor.put(key.classSignature(), constructor);
                        }
                    }
                }
            }
            if (!permissionCheckers.isEmpty()) {
                if (permissionCheckers.size() > 1) {
                    throw new RuntimeException("""
                            Found @PermissionChecker annotation instances that authorize the '%s' permissions, however
                            no @PermissionsAllowed annotation instance requires these permissions
                            """.formatted(String.join(",", permissionCheckers.values())));
                } else {
                    throw new RuntimeException("""
                            Found @PermissionChecker annotation instance that authorize the '%s' permission, however
                            no @PermissionsAllowed annotation instance requires this permission
                            """.formatted(permissionCheckers.values().iterator().next()));
                }
            }
            return this;
        }

        PermissionSecurityChecksBuilder gatherPermissionsAllowedAnnotations(
                Map<MethodInfo, AnnotationInstance> alreadyCheckedMethods,
                Map<ClassInfo, AnnotationInstance> alreadyCheckedClasses,
                List<AnnotationInstance> additionalClassInstances,
                Predicate<MethodInfo> hasAdditionalSecurityAnnotations) {

View on GitHub (pinned to e1c734241f)

Solutions

  1. Add @PermissionsAllowed("<name>") on the resource methods that should require each checker's permission
  2. Fix typos so the permission name matches exactly between checker and requirement
  3. Remove the now-unused @PermissionChecker methods

Example fix

// before
@PermissionChecker("book:read") boolean canRead(...) {...}
// (no @PermissionsAllowed anywhere)

// after
@PermissionChecker("book:read") boolean canRead(...) {...}
// in the resource:
@PermissionsAllowed("book:read")
public Book get(Long id) {...}
Defensive patterns

Strategy: validation

Validate before calling

// every checker value must appear in some @PermissionsAllowed
Set<String> required = scanForPermissionsAllowedValues();
Set<String> provided = scanForPermissionCheckerValues();
Set<String> unmatched = new HashSet<>(provided); unmatched.removeAll(required);
if (unmatched.size() > 1) throw new IllegalStateException("Unmatched checkers: " + unmatched);

Prevention

When it happens

Trigger: Declaring two or more @PermissionChecker methods whose permission values never appear in any @PermissionsAllowed annotation on endpoints/methods — detected in validatePermissionClasses after gathering all required permission keys.

Common situations: Removing/refactoring the secured endpoints (or their @PermissionsAllowed) while leaving the checkers; typos in permission names so the sets don't intersect; checkers in a library module whose consumers never use them.

Related errors


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