{"record":{"id":"21e169c1544dc00e","repo":"quarkusio/quarkus","slug":"found-permissionchecker-annotation-instance-that","errorCode":null,"errorMessage":"Found @PermissionChecker annotation instance that authorize the '%s' permission, however\n                            no @PermissionsAllowed annotation instance requires this permission\n                            ","messagePattern":"Found @PermissionChecker annotation instance that authorize the '(.+?)' permission, however\n                            no @PermissionsAllowed annotation instance requires this permission\n                            ","errorType":"exception","errorClass":"java.lang.RuntimeException","httpStatus":null,"severity":"error","filePath":"extensions/security/deployment/src/main/java/io/quarkus/security/deployment/PermissionSecurityChecks.java","lineNumber":421,"sourceCode":"                                                clazz.name().toString(), String.class.getName()));\n                            }\n                            // rest of validation needs to be done for computed classes only and per each secured method\n                            // therefore we do it later\n\n                            // cache validation result\n                            classSignatureToConstructor.put(key.classSignature(), constructor);\n                        }\n                    }\n                }\n            }\n            if (!permissionCheckers.isEmpty()) {\n                if (permissionCheckers.size() > 1) {\n                    throw new RuntimeException(\"\"\"\n                            Found @PermissionChecker annotation instances that authorize the '%s' permissions, however\n                            no @PermissionsAllowed annotation instance requires these permissions\n                            \"\"\".formatted(String.join(\",\", permissionCheckers.values())));\n                } else {\n                    throw new RuntimeException(\"\"\"\n                            Found @PermissionChecker annotation instance that authorize the '%s' permission, however\n                            no @PermissionsAllowed annotation instance requires this permission\n                            \"\"\".formatted(permissionCheckers.values().iterator().next()));\n                }\n            }\n            return this;\n        }\n\n        PermissionSecurityChecksBuilder gatherPermissionsAllowedAnnotations(\n                Map<MethodInfo, AnnotationInstance> alreadyCheckedMethods,\n                Map<ClassInfo, AnnotationInstance> alreadyCheckedClasses,\n                List<AnnotationInstance> additionalClassInstances,\n                Predicate<MethodInfo> hasAdditionalSecurityAnnotations) {\n\n            List<PermissionKey> cache = new ArrayList<>();\n            Map<MethodInfo, List<List<PermissionKey>>> classMethodToPermissionKeys = new HashMap<>();\n            for (AnnotationInstance instance : permissionInstances) {\n","sourceCodeStart":403,"sourceCodeEnd":439,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/security/deployment/src/main/java/io/quarkus/security/deployment/PermissionSecurityChecks.java#L403-L439","documentation":"A single @PermissionChecker was registered but no @PermissionsAllowed annotation requires its permission. Quarkus validates that every registered checker is actually consumed; an unconsumed checker is almost certainly a naming typo or leftover code, so the build fails. This is the singular variant of the unmatched-checker error.","triggerScenarios":"Declaring exactly one @PermissionChecker method whose 'value' does not appear in any @PermissionsAllowed in the application, found by validatePermissionClasses at build time.","commonSituations":"Typos in the permission string ('book:read' vs 'books:read'); deleting the secured endpoint during refactoring; moving @PermissionsAllowed to a different annotation value.","solutions":["Add @PermissionsAllowed with the exact checker permission name to the protected method","Correct the permission string so the checker and requirement match character-for-character","Remove the @PermissionChecker method if the check is no longer needed"],"exampleFix":"// before\n@PermissionChecker(\"book:read\") boolean canRead(...) {...}\n@PermissionsAllowed(\"books:read\") public Book get(Long id) {...}\n\n// after\n@PermissionChecker(\"book:read\") boolean canRead(...) {...}\n@PermissionsAllowed(\"book:read\") public Book get(Long id) {...}","handlingStrategy":"validation","validationCode":"String checkerValue = \"book:read\";\nif (!scanForPermissionsAllowedValues().contains(checkerValue))\n    throw new IllegalStateException(\"No @PermissionsAllowed requires permission \" + checkerValue);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Extract permission names to shared constants used by both checker and @PermissionsAllowed","Before deleting a secured endpoint, delete its checker too","Run the application build locally before pushing; this error surfaces at build time"],"tags":["quarkus","security","build-time","permissions-allowed","wiring"],"backgroundTag":"unused-permission-checker","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}