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
- Move the security annotation to the overriding implementation method in the concrete class.
- Convert the default method to an abstract interface method and implement it in each implementing class with the annotation.
- 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
- Never annotate interface default methods with @RolesAllowed/@Authenticated
- Keep security annotations on classes/method implementations only
- Review refactors that move annotated code into interfaces
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
- Private method '' cannot be annotated with the @PermissionCh
- Static method '' cannot be annotated with the @PermissionChe
- Unable to determine if the '${unsecuredMethod}' method shoul
- The '%s' CDI bean injection point was detected, but there is
- The @Blocking, @NonBlocking and @RunOnVirtualThread annotati
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/fb7a5f2c6acaa9c3.
Report an issue: GitHub.