quarkusio/quarkus · error · RuntimeException

Interface '${declaringClass}' default method '${method}' has

Error message

Interface '${declaringClass}' default method '${method}' has security annotation.
Securing interface default methods is currently not supported, please secure
the interface implementation method instead.

What it means

CDI interceptors (which enforce @RolesAllowed etc.) are not applied to interface default methods. Quarkus therefore fails the build when it detects a security annotation on a default method of a secured interface, telling the developer to secure the implementing method instead.

Source

Thrown at extensions/security/spi/src/main/java/io/quarkus/security/spi/SecurityTransformerBuildItem.java:536

            // add security annotation instances from interfaces direct implementors
            var result = new HashSet<>(indexedAnnotationInstances);
            for (var annotationInstance : indexedAnnotationInstances) {
                final ClassInfo declaringClass;
                if (annotationInstance.target().kind() == METHOD) {
                    declaringClass = annotationInstance.target().asMethod().declaringClass();
                } else if (annotationInstance.target().kind() == CLASS) {
                    declaringClass = annotationInstance.target().asClass();
                } else {
                    // illegal state - this shouldn't happen
                    continue;
                }
                if (shouldCheckForSecurityAnnotations(declaringClass, checkedInterfaces)) {
                    // test that secured interface doesn't have default methods with security annotations
                    // as CDI interceptors are not applied on them
                    for (var securedInterfaceMethod : declaringClass.methods()) {
                        if (securedInterfaceMethod.isDefault()
                                && hasSecurityAnnotationDetectedByIndex(securedInterfaceMethod, annotationOverlay.index())) {
                            throw new RuntimeException("""
                                    Interface '%s' default method '%s' has security annotation.
                                    Securing interface default methods is currently not supported, please secure
                                    the interface implementation method instead.
                                    """.formatted(declaringClass.name().toString(), securedInterfaceMethod.name()));
                        }
                    }

                    var implementorSecurityAnnotation = getImplementorsSecurityAnnotations(securityAnnotationName,
                            declaringClass, repeatable);
                    if (implementorSecurityAnnotation != null) {
                        result.addAll(implementorSecurityAnnotation);
                    }
                }
            }
            return Collections.unmodifiableCollection(result);
        }
    }

View on GitHub (pinned to e1c734241f)

Solutions

  1. Move the security annotation to the overriding implementation method in the concrete class.
  2. Convert the default method to an abstract interface method and implement it in each implementing class with the annotation.
  3. Extract shared logic into a helper bean and keep the security annotation on the concrete endpoint method.

Example fix

// before
interface Greeting {
    @RolesAllowed("admin")
    default String hello() { return "hi"; }
}

// after
class GreetingImpl implements Greeting {
    @RolesAllowed("admin")
    public String hello() { return "hi"; }
}
Defensive patterns

Strategy: validation

Validate before calling

boolean ok(java.lang.Class<?> iface) {
    for (java.lang.reflect.Method m : iface.getMethods()) {
        if (m.isDefault() && m.getAnnotations().length > 0
                && hasSecurityAnnotation(m)) return false;
    }
    return true;
}

Prevention

When it happens

Trigger: Declaring an interface whose default method is annotated with @RolesAllowed/@Authenticated/@PermitAll while the interface is checked for security annotations (e.g. implemented by a CDI bean or REST resource).

Common situations: Adding default convenience methods with security annotations to a shared API interface; refactoring duplicated annotated code into interface default methods; copy-pasting annotated endpoint signatures into interfaces.

Related errors


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