quarkusio/quarkus · error · IllegalStateException
Class %s is annotated with multiple security annotations %s
Error message
Class %s is annotated with multiple security annotations %s and %s
What it means
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.
Source
Thrown at extensions/security/deployment/src/main/java/io/quarkus/security/deployment/SecurityProcessor.java:1527
}
private void gatherClassSecurityAnnotations() {
// now add the class annotations to methods if they haven't already been annotated
for (AnnotationInstance instance : annotationInstances) {
AnnotationTarget target = instance.target();
if (target.kind() == AnnotationTarget.Kind.CLASS) {
List<MethodInfo> methods = target.asClass().methods();
AnnotationInstance existingClassInstance = classLevelAnnotations.get(target.asClass());
if (existingClassInstance == null) {
classLevelAnnotations.put(target.asClass(), instance);
for (MethodInfo methodInfo : methods) {
AnnotationInstance alreadyExistingInstance = alreadyCheckedMethods.get(methodInfo);
if ((alreadyExistingInstance == null) && !hasAdditionalSecurityAnnotation.test(methodInfo)) {
putResult.accept(methodInfo, instance);
}
}
} else {
throw new IllegalStateException(
"Class " + target.asClass() + " is annotated with multiple security annotations "
+ instance.name()
+ " and " + existingClassInstance.name());
}
}
}
}
private void gatherMethodSecurityAnnotations() {
// make sure we process annotations on methods first
for (AnnotationInstance instance : annotationInstances) {
AnnotationTarget target = instance.target();
if (target.kind() == AnnotationTarget.Kind.METHOD) {
MethodInfo methodInfo = target.asMethod();
if (alreadyCheckedMethods.containsKey(methodInfo) || hasAdditionalSecurityAnnotation.test(methodInfo)) {
throw new IllegalStateException(
"Method " + methodInfo.name() + " of class " + methodInfo.declaringClass()View on GitHub (pinned to e1c734241f)
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.
Example fix
// before
@RolesAllowed("admin")
@Authenticated
public class AdminResource { ... }
// after
@RolesAllowed("admin")
public class AdminResource { ... } Defensive patterns
Strategy: validation
Validate before calling
// check class-level annotations before build
long n = Stream.of(RolesAllowed.class, Authenticated.class, PermissionsAllowed.class, DenyAll.class)
.filter(a -> targetClass.isAnnotationPresent(a)).count();
if (n > 1) throw new IllegalStateException("multiple class security annotations"); Prevention
- One class-level security annotation only
- Express combined constraints in a single annotation
- Review annotations after refactors/copy-paste
When it happens
Trigger: A class is annotated with two different security annotations, e.g. both @RolesAllowed("admin") and @Authenticated, or @PermissionsAllowed plus @RolesAllowed at class level.
Common situations: 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.
Related errors
- Method %s#%s should not have been added as an additional sec
- Method %s of class %s is annotated with multiple security an
- @PermissionChecker annotation placed on the '%s' attribute '
- @PermissionChecker annotation instance placed on the '%s' re
- Detected two @PermissionChecker annotations with same value
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/69bbce1292f95a64.
Report an issue: GitHub.