quarkusio/quarkus · error · RuntimeException
Security annotations '<annotations>' cannot be applied on th
Error message
Security annotations '<annotations>' cannot be applied on the '<method>' method, please move the annotations to the class-level instead
What it means
When an endpoint class already has a class-level security annotation (e.g. @Basic), placing a method-level security annotation on one of its methods is rejected: the class-level mechanism governs and a per-method override of that category is not allowed. The build fails and points at the offending method, advising to consolidate annotations at class level.
Source
Thrown at extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/HttpSecurityProcessor.java:892
for (MethodInfo method : interceptedClass.methods()) {
if (hasProperEndpointModifiers(method)) {
// avoid situation when resource method is annotated with @Basic, class is annotated
// with @Bearer, and we apply the @Bearer annotation
boolean interceptorBindingNotAppliedOnMethodLevel = !cache.containsKey(method)
|| !cache.get(method).contains(interceptorBinding);
if (interceptorBindingNotAppliedOnMethodLevel) {
addInterceptedEndpoint(method, annotation, annotationBinding,
bindingValueToInterceptedMethods, interceptorBinding);
}
}
}
} else {
MethodInfo mi = annotation.target().asMethod();
if (hasClassLevelSecurity.test(mi.declaringClass())) {
throw new RuntimeException(
("Security annotations '%s' cannot be applied on the '%s' method, "
+ "please move the annotations to the class-level instead").formatted(
Arrays.toString(Arrays.stream(interceptorBinding.getAnnotationBindings())
.toArray()),
toTargetName(mi)));
} else {
// only allow to combine interceptor bindings on endpoints if we explicitly support it
var appliedBindings = cache.computeIfAbsent(mi, a -> new ArrayList<>());
if (appliedBindings.contains(interceptorBinding)) {
if (!interceptorBinding.allowToRepeatThisInterceptorBinding()) {
throw new RuntimeException(
"Only one of the '%s' annotations can be applied on the '%s' method".formatted(
Arrays.toString(interceptorBinding.getAnnotationBindings()),
toTargetName(mi)));
}
} else {
appliedBindings.add(interceptorBinding);
}View on GitHub (pinned to e1c734241f)
Solutions
- Remove the method-level security annotation and rely on the class-level one
- Change the class-level annotation to the mechanism you actually need
- Remove the class-level annotation and annotate each method individually instead
Example fix
// before
@Basic
public class UserResource {
@Form
@GET
public String get() { ... }
}
// after
@Basic
public class UserResource {
@GET
public String get() { ... }
} Defensive patterns
Strategy: validation
Validate before calling
if (Resource.class.isAnnotationPresent(Basic.class)
&& Arrays.stream(Resource.class.getDeclaredMethods())
.anyMatch(m -> m.isAnnotationPresent(Form.class))) {
throw new IllegalStateException("Method-level security annotation conflicts with class-level one");
} Prevention
- Never mix class-level and method-level mechanism annotations on the same resource
- Consolidate security annotations at class level when the whole class shares a mechanism
- Use per-method annotations only when the class has none
When it happens
Trigger: Annotating a method with an auth mechanism annotation (e.g. @Form) inside a class already annotated with a class-level security annotation (e.g. @Basic).
Common situations: Trying to 'override' the class mechanism for one endpoint; adding a new method with a copied annotation from another class; incremental security tightening that collided with existing class-level config.
Related errors
- @PermissionChecker annotation placed on the '%s' attribute '
- The @AuthorizationPolicy annotation placed on '<target>' mus
- Only one of the '<annotations>' annotations can be applied o
- Only one of the '<annotations>' annotations can be applied o
- The configuration ${clazz} is missing the @ConfigRoot annota
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/8ea126c74d108cf5.
Report an issue: GitHub.