{"record":{"id":"69bbce1292f95a64","repo":"quarkusio/quarkus","slug":"class-s-is-annotated-with-multiple-security-annot-69bbce","errorCode":null,"errorMessage":"Class %s is annotated with multiple security annotations %s and %s","messagePattern":"Class (.+?) is annotated with multiple security annotations (.+?) and (.+?)","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"extensions/security/deployment/src/main/java/io/quarkus/security/deployment/SecurityProcessor.java","lineNumber":1527,"sourceCode":"        }\n\n        private void gatherClassSecurityAnnotations() {\n            // now add the class annotations to methods if they haven't already been annotated\n            for (AnnotationInstance instance : annotationInstances) {\n                AnnotationTarget target = instance.target();\n                if (target.kind() == AnnotationTarget.Kind.CLASS) {\n                    List<MethodInfo> methods = target.asClass().methods();\n                    AnnotationInstance existingClassInstance = classLevelAnnotations.get(target.asClass());\n                    if (existingClassInstance == null) {\n                        classLevelAnnotations.put(target.asClass(), instance);\n                        for (MethodInfo methodInfo : methods) {\n                            AnnotationInstance alreadyExistingInstance = alreadyCheckedMethods.get(methodInfo);\n                            if ((alreadyExistingInstance == null) && !hasAdditionalSecurityAnnotation.test(methodInfo)) {\n                                putResult.accept(methodInfo, instance);\n                            }\n                        }\n                    } else {\n                        throw new IllegalStateException(\n                                \"Class \" + target.asClass() + \" is annotated with multiple security annotations \"\n                                        + instance.name()\n                                        + \" and \" + existingClassInstance.name());\n                    }\n                }\n\n            }\n        }\n\n        private void gatherMethodSecurityAnnotations() {\n            // make sure we process annotations on methods first\n            for (AnnotationInstance instance : annotationInstances) {\n                AnnotationTarget target = instance.target();\n                if (target.kind() == AnnotationTarget.Kind.METHOD) {\n                    MethodInfo methodInfo = target.asMethod();\n                    if (alreadyCheckedMethods.containsKey(methodInfo) || hasAdditionalSecurityAnnotation.test(methodInfo)) {\n                        throw new IllegalStateException(\n                                \"Method \" + methodInfo.name() + \" of class \" + methodInfo.declaringClass()","sourceCodeStart":1509,"sourceCodeEnd":1545,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/security/deployment/src/main/java/io/quarkus/security/deployment/SecurityProcessor.java#L1509-L1545","documentation":"Quarkus allows at most one security annotation per class. When a class-level annotation is scanned and another class-level security annotation already exists for the same target class, the build fails because it cannot decide which check to enforce.","triggerScenarios":"A class is annotated with two different security annotations, e.g. both @RolesAllowed(\"admin\") and @Authenticated, or @PermissionsAllowed plus @RolesAllowed at class level.","commonSituations":"Copy-pasting security annotations from different examples; a superclass/framework annotation plus a manually added one on the same class; refactoring that left an old annotation behind.","solutions":["Keep exactly one class-level security annotation; express combined requirements with @PermissionsAllowed or role strings in @RolesAllowed (e.g. @RolesAllowed({\"admin\",\"user\"})).","If different behavior is needed per method, move one annotation to the method level instead of stacking at class level.","Delete the stale/redundant annotation found by searching the class for @RolesAllowed/@Authenticated/@PermissionsAllowed/@DenyAll."],"exampleFix":"// before\n@RolesAllowed(\"admin\")\n@Authenticated\npublic class AdminResource { ... }\n// after\n@RolesAllowed(\"admin\")\npublic class AdminResource { ... }","handlingStrategy":"validation","validationCode":"// check class-level annotations before build\nlong n = Stream.of(RolesAllowed.class, Authenticated.class, PermissionsAllowed.class, DenyAll.class)\n    .filter(a -> targetClass.isAnnotationPresent(a)).count();\nif (n > 1) throw new IllegalStateException(\"multiple class security annotations\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["One class-level security annotation only","Express combined constraints in a single annotation","Review annotations after refactors/copy-paste"],"tags":["quarkus","security","build-time","duplicate-annotation"],"backgroundTag":"conflicting-security-annotations","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"}