{"record":{"id":"b81e71d9f966d6a2","repo":"quarkusio/quarkus","slug":"an-invalid-security-annotation-combination-was-det-b81e71","errorCode":null,"errorMessage":"An invalid security annotation combination was detected: Found <instance> and <securityAnnotation> on method <method>","messagePattern":"An invalid security annotation combination was detected: Found <instance> and <securityAnnotation> on method <method>","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"extensions/spring-security/deployment/src/main/java/io/quarkus/spring/security/deployment/SpringSecurityProcessor.java","lineNumber":196,"sourceCode":"                        .withoutPackagePrefix();\n                throw new IllegalArgumentException(\"An invalid security annotation combination was detected: Found @\"\n                        + instance.name().withoutPackagePrefix() + \" and @\" + securityAnnotationName + \" on class \"\n                        + classInfo.simpleName());\n            }\n        }\n    }\n\n    //Validates that there is no @Secured with the standard security annotations at method level\n    private void checksStandardSecurity(AnnotationInstance instance, MethodInfo methodInfo,\n            SecurityTransformer securityTransformer) {\n        if (securityTransformer.hasSecurityAnnotation(methodInfo)) {\n            Optional<AnnotationInstance> firstStandardSecurityAnnotation = securityTransformer\n                    .findFirstSecurityAnnotation(methodInfo);\n            if (firstStandardSecurityAnnotation.isPresent()) {\n                String securityAnnotationName = securityTransformer.findFirstSecurityAnnotation(methodInfo).get()\n                        .name()\n                        .withoutPackagePrefix();\n                throw new IllegalArgumentException(\"An invalid security annotation combination was detected: Found \"\n                        + instance.name().withoutPackagePrefix() + \" and \" + securityAnnotationName + \" on method \"\n                        + methodInfo.name());\n            }\n        }\n    }\n\n    private boolean isPublicNonStaticNonConstructor(MethodInfo methodInfo) {\n        return Modifier.isPublic(methodInfo.flags()) && !Modifier.isStatic(methodInfo.flags())\n                && !\"<init>\".equals(methodInfo.name());\n    }\n\n    @BuildStep\n    void locatePreAuthorizedInstances(\n            CombinedIndexBuildItem index,\n            BuildProducer<SpringPreAuthorizeAnnotatedMethodBuildItem> springPreAuthorizeAnnotatedMethods,\n            BuildProducer<AnnotationsTransformerBuildItem> annotationsTransformer,\n            Optional<SecurityTransformerBuildItem> securityTransformerBuildItem) {\n        SecurityTransformer securityTransformer = SecurityTransformerBuildItem.createSecurityTransformer(index.getIndex(),","sourceCodeStart":178,"sourceCodeEnd":214,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/spring-security/deployment/src/main/java/io/quarkus/spring/security/deployment/SpringSecurityProcessor.java#L178-L214","documentation":"Same annotation-conflict rule as the class-level check, but applied to methods: a method cannot be annotated with both a Spring Security annotation and a standard Quarkus security annotation. checksStandardSecurity throws this IllegalArgumentException at build time, listing both annotation names and the method.","triggerScenarios":"A method is annotated with, for example, both @PreAuthorize(\"hasRole('admin')\") and @RolesAllowed(\"admin\"), detected while locating @PreAuthorize/@Secured instances on methods.","commonSituations":"Adding a Spring Security expression to an endpoint that already had @RolesAllowed; a refactoring that merged two secured handlers; copy-paste of annotations from different codebases.","solutions":["Delete one of the two annotations on the method","Keep the Spring Security annotation and remove @RolesAllowed (or the reverse) on that method","Unify the project on one security annotation style to avoid recurrence"],"exampleFix":"// before\n@PreAuthorize(\"hasRole('ROLE_ADMIN')\")\n@RolesAllowed(\"admin\")\npublic void delete(String id) { }\n\n// after\n@PreAuthorize(\"hasRole('ROLE_ADMIN')\")\npublic void delete(String id) { }","handlingStrategy":"validation","validationCode":"Method m = AdminResource.class.getMethod(\"delete\", String.class);\nboolean spring = m.isAnnotationPresent(PreAuthorize.class) || m.isAnnotationPresent(Secured.class);\nboolean standard = m.isAnnotationPresent(RolesAllowed.class) || m.isAnnotationPresent(PermitAll.class);\nif (spring && standard) throw new IllegalStateException(\"Mixed security annotations on method\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never combine @PreAuthorize/@Secured with @RolesAllowed/@PermitAll on the same method","Review security annotations when copy-pasting endpoint code","Standardize on one mechanism (Quarkus standard or Spring-style) across the project"],"tags":["spring-security","build-time","annotation-conflict","roles-allowed"],"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-14T00:17:10.932Z"}