quarkusio/quarkus · error · java.lang.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
A class was annotated with @PermissionsAllowed and also with another class-level security annotation (e.g. @Authenticated, @RolesAllowed). Combining @PermissionsAllowed with other security annotations at class level is not allowed because it makes authorization ambiguous; Quarkus reports the two conflicting annotation names and fails the build.
Source
Thrown at extensions/security/deployment/src/main/java/io/quarkus/security/deployment/PermissionSecurityChecks.java:497
}
if (hasAdditionalSecurityAnnotations.test(methodInfo)) {
continue;
}
// ignore method annotated with other security annotation
boolean noMethodLevelSecurityAnnotation = !alreadyCheckedMethods.containsKey(methodInfo);
// ignore method annotated with method-level @PermissionsAllowed
boolean noMethodLevelPermissionsAllowed = !targetToPermissionKeys.containsKey(methodInfo);
if (noMethodLevelSecurityAnnotation && noMethodLevelPermissionsAllowed) {
gatherPermissionKeys(instance, methodInfo, cache, classMethodToPermissionKeys);
}
}
} else {
// we do not allow combining @PermissionsAllowed with other security annotations as @Authenticated
throw new IllegalStateException(
String.format("Class %s is annotated with multiple security annotations %s and %s", clazz,
instance.name(), existingClassInstance.name()));
}
}
}
}
targetToPermissionKeys.putAll(classMethodToPermissionKeys);
for (var instance : additionalClassInstances) {
gatherPermissionKeys(instance, instance.target(), cache, targetToPermissionKeys);
}
// for validation purposes, so that we detect correctly combinations with other security annotations
var targetInstances = new ArrayList<>(permissionInstances);
targetInstances.addAll(additionalClassInstances);
targetToPermissionKeys.keySet().forEach(at -> {
if (at.kind() == AnnotationTarget.Kind.CLASS) {
var classInfo = at.asClass();
alreadyCheckedClasses.put(classInfo, getAnnotationInstance(classInfo, targetInstances));View on GitHub (pinned to e1c734241f)
Solutions
- Remove the other class-level security annotation, keeping only @PermissionsAllowed
- Convert the other annotation's policy into a @PermissionChecker + permission name used by @PermissionsAllowed
- If both policies are genuinely needed, apply them at different levels consistently within one annotation system
Example fix
// before
@Authenticated
@PermissionsAllowed(value="book:read", action=BookPerm.class)
public class BookResource {...}
// after
@PermissionsAllowed(value="book:read", action=BookPerm.class)
public class BookResource {...} Defensive patterns
Strategy: validation
Validate before calling
for (Annotation a : BookResource.class.getAnnotations()) {
if (!(a instanceof PermissionsAllowed) && SECURITY_ANNOTATIONS.contains(a.annotationType()))
throw new IllegalStateException("@PermissionsAllowed must not be combined with " + a.annotationType());
} Prevention
- Pick one authorization model (RBAC or permission checkers) per class
- Review class-level annotations when introducing @PermissionsAllowed
- Keep security annotations in the class Javadoc for visibility
When it happens
Trigger: Placing @PermissionsAllowed on a class that also carries @Authenticated/@RolesAllowed/@DenyAll etc.; detected in gatherPermissionsAllowedAnnotations when an existingClassInstance for the same class has a different annotation name.
Common situations: Adding @PermissionsAllowed to an already-secured class when tightening authorization; applying annotations from different security generations (legacy RBAC vs the permission-checker API) to the same bean.
Related errors
- 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
- @PermissionChecker method '%s' declares checked exceptions w
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/f8e3888d59b4c328.
Report an issue: GitHub.