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
- Do not produce an AdditionalSecuredBuildItem for methods already annotated with @RolesAllowed; filter such methods in the producing build step.
- Remove the redundant @RolesAllowed from the method if the additional secured item should own the security config.
- 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
- Check for existing @RolesAllowed before emitting AdditionalSecuredBuildItem
- Centralize automatic securing logic so duplicates cannot arise
- Document which classes/methods your extension secures automatically
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
- Found %d DefaultSecurityCheckBuildItem items, please make su
- Detected two @PermissionChecker annotations with same value
- A generic type is not allowed here; try creating a subclass
- Build item class must be leaf (final) types: %s
- Cannot construct empty build items
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/e764a55be6753a7f.
Report an issue: GitHub.