quarkusio/quarkus · error · DeploymentException
Method '' of class '' contains multiple HTTP method annotati
Error message
Method '' of class '' contains multiple HTTP method annotations.
What it means
EndpointIndexer.validateHttpAnnotations checks that a JAX-RS resource method carries at most one HTTP method annotation (@GET, @POST, @PUT, etc.). If two recognized HTTP method annotations are present on the same method, createEndpoints fails with a DeploymentException naming the method and class. A resource method must map to exactly one HTTP verb.
Source
Thrown at independent-projects/resteasy-reactive/common/processor/src/main/java/org/jboss/resteasy/reactive/common/processor/EndpointIndexer.java:540
* By default, we are not removing the trailing slash.
*/
protected String handleTrailingSlash(String path) {
return path;
}
private void validateHttpAnnotations(MethodInfo info) {
List<AnnotationInstance> annotationInstances = info.annotations();
Set<DotName> allMethodAnnotations = new HashSet<>(annotationInstances.size());
for (AnnotationInstance instance : annotationInstances) {
allMethodAnnotations.add(instance.name());
}
int httpAnnotationCount = 0;
for (DotName dotName : allMethodAnnotations) {
if (httpAnnotationToMethod.containsKey(dotName)) {
httpAnnotationCount++;
}
if (httpAnnotationCount > 1) {
throw new DeploymentException("Method '" + info.name() + "' of class '" + info.declaringClass().name()
+ "' contains multiple HTTP method annotations.");
}
}
}
private static boolean hasProperModifiers(MethodInfo info) {
if (isSynthetic(info.flags())) {
log.debug("Method '" + info.name() + " of Resource class '" + info.declaringClass().name()
+ "' is a synthetic method and will therefore be ignored");
return false;
}
if ((info.flags() & Modifier.PUBLIC) == 0) {
log.warn("Method '" + info.name() + " of Resource class '" + info.declaringClass().name()
+ "' is not public and will therefore be ignored");
return false;
}
if ((info.flags() & Modifier.STATIC) != 0) {
log.warn("Method '" + info.name() + " of Resource class '" + info.declaringClass().name()View on GitHub (pinned to e1c734241f)
Solutions
- Remove one of the HTTP method annotations so the method handles a single verb
- Split the logic into two methods, one per HTTP verb
- If multiple verbs should be handled, implement @OPTIONS/@HttpMethod overloads as separate methods or use a custom annotation only for verbs not built in
Example fix
// before
@Path("/item")
@GET
@POST
public Item getOrCreate() { ... }
// after
@GET public Item get() { ... }
@POST public Item create() { ... } Defensive patterns
Strategy: validation
Validate before calling
long httpAnnotations = Arrays.stream(method.getAnnotations())
.map(Annotation::annotationType)
.filter(t -> t.isAnnotationPresent(HttpMethod.class))
.distinct().count();
if (httpAnnotations > 1) throw new IllegalStateException("Multiple HTTP verbs on " + method); Prevention
- One verb annotation per resource method
- Split multi-verb handling into separate methods
- Review custom @HttpMethod annotations for clashes
- Enable Quarkus dev-mode which surfaces this at startup
When it happens
Trigger: Annotating one resource method with two HTTP verb annotations, e.g. both @GET and @POST, or a custom @HttpMethod annotation combined with a standard one, discovered while indexing the class.
Common situations: Copy-paste of annotations intending 'supports GET or POST'; a custom @HttpMethod meta-annotation whose name clashes with a built-in one; accidental duplicate annotations after merging branches.
Related errors
- More than one Application class: ${jakartaRestApplicationCla
- Usage of '@Inject' is not allowed in 'jakarta.ws.rs.core.App
- Unable to handle class: ${applicationClass}
- @Compressed and @Uncompressed cannot be both declared on res
- Non static nested resources classes are not supported: '
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/5491a0420c49a2e0.
Report an issue: GitHub.