quarkusio/quarkus · error · IllegalStateException

Method %s#%s should not have been added as an additional sec

Error message

Method %s#%s should not have been added as an additional secured method as it's already annotated with @RolesAllowed.

What it means

When an additional secured method (added via AdditionalSecuredBuildItem) targets a method already annotated with @RolesAllowed, Quarkus detects it would have to apply a second @RolesAllowed annotation, which is illegal, and aborts the build. This is an internal consistency check indicating a producer added a redundant/contradictory additional secured method.

Source

Thrown at extensions/security/deployment/src/main/java/io/quarkus/security/deployment/SecurityProcessor.java:1135

        /*
         * Handle additional secured methods by adding the denyAll/rolesAllowed check to all public non-static methods
         * that don't have same security annotations
         */
        for (AdditionalSecured additionalSecuredMethod : additionalSecuredMethods) {
            if (!isPublicNonStaticNonConstructor(additionalSecuredMethod.methodInfo)) {
                continue;
            }
            if (hasAdditionalSecurityAnnotations.test(additionalSecuredMethod.methodInfo)) {
                continue;
            }
            AnnotationInstance alreadyExistingInstance = methodToInstanceCollector.get(additionalSecuredMethod.methodInfo);
            if (additionalSecuredMethod.rolesAllowed.isPresent()) {
                if (alreadyExistingInstance == null) {
                    methodToRoles.put(additionalSecuredMethod.methodInfo,
                            additionalSecuredMethod.rolesAllowed.get().toArray(String[]::new));
                } else if (alreadyHasAnnotation(alreadyExistingInstance, ROLES_ALLOWED)) {
                    // we should not try to add second @RolesAllowed
                    throw new IllegalStateException("Method " + additionalSecuredMethod.methodInfo.declaringClass() + "#"
                            + additionalSecuredMethod.methodInfo.name() + " should not have been added as an additional "
                            + "secured method as it's already annotated with @RolesAllowed.");
                }
            } else {
                if (alreadyExistingInstance == null) {
                    result.put(additionalSecuredMethod.methodInfo, recorder.denyAll());
                } else if (alreadyHasAnnotation(alreadyExistingInstance, DENY_ALL)) {
                    // we should not try to add second @DenyAll
                    throw new IllegalStateException("Method " + additionalSecuredMethod.methodInfo.declaringClass() + "#"
                            + additionalSecuredMethod.methodInfo.name() + " should not have been added as an additional "
                            + "secured method as it's already annotated with @DenyAll.");
                }
            }
        }

        // create roles allowed security checks
        // we create only one security check for each role set
        Map<Set<String>, SecurityCheck> cache = new HashMap<>();

View on GitHub (pinned to e1c734241f)

Solutions

  1. Do not produce an AdditionalSecuredBuildItem for methods already annotated with @RolesAllowed; filter such methods in the producing build step.
  2. Remove the redundant @RolesAllowed from the method if the additional secured item should own the security config.
  3. If roles should merge, handle merging logic in your own build step before producing the item, instead of emitting a duplicate.

Example fix

// before
// extension produces additional secured item for method annotated @RolesAllowed("admin")

// after
if (methodInfo.hasAnnotation(ROLES_ALLOWED)) return; // skip already-secured methods in your build step
Defensive patterns

Strategy: validation

Validate before calling

// in your build step, skip methods already carrying @RolesAllowed
if (methodInfo.hasAnnotation("jakarta.annotation.security.RolesAllowed")) return null;

Prevention

When it happens

Trigger: A custom extension produces an AdditionalSecuredBuildItem for a method that already has @RolesAllowed, while that method also already has a security annotation instance in the build (alreadyExistingInstance with ROLES_ALLOWED).

Common situations: Custom extension automatically securing endpoints that are already secured by @RolesAllowed in application code; misconfigured additionalSecured rolesAllowed on an annotated legacy class.

Related errors


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