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

  1. Keep exactly one class-level security annotation; express combined requirements with @PermissionsAllowed or role strings in @RolesAllowed (e.g. @RolesAllowed({"admin","user"})).
  2. If different behavior is needed per method, move one annotation to the method level instead of stacking at class level.
  3. 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

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


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