quarkusio/quarkus · error · DeploymentException
'@FormParam' and '@RestForm' can only be used on methods ann
Error message
'@FormParam' and '@RestForm' can only be used on methods annotated with '@Consumes(MediaType.MULTIPART_FORM_DATA)' '@Consumes(MediaType.APPLICATION_FORM_URLENCODED)'. Offending method is '%s#%s'
What it means
Methods using @FormParam/@RestForm must declare @Consumes of either multipart/form-data or application/x-www-form-urlencoded, because form parameters can only be extracted from those media types. EndpointIndexer validates the method's @Produces/@Consumes metadata during deployment and throws if no valid consumes value is present.
Source
Thrown at independent-projects/resteasy-reactive/common/processor/src/main/java/org/jboss/resteasy/reactive/common/processor/EndpointIndexer.java:684
&& !bodyParamType.name().equals(ResteasyReactiveDotNames.MULTI_VALUED_MAP)
&& !bodyParamType.name().equals(ResteasyReactiveDotNames.STRING)) {
throw new DeploymentException(String.format(
"'@FormParam' and '@RestForm' cannot be used in a resource method that contains a body parameter. Offending method is "
+ "'%s#%s'",
currentMethodInfo.declaringClass().name(), currentMethodInfo));
}
boolean validConsumes = false;
if (consumes != null && consumes.length > 0) {
for (String c : consumes) {
if (c.startsWith(MediaType.MULTIPART_FORM_DATA)
|| c.startsWith(MediaType.APPLICATION_FORM_URLENCODED)) {
validConsumes = true;
break;
}
}
// TODO: does it make sense to default to MediaType.MULTIPART_FORM_DATA when no consumes is set?
if (!validConsumes) {
throw new DeploymentException(String.format(
"'@FormParam' and '@RestForm' can only be used on methods annotated with '@Consumes(MediaType.MULTIPART_FORM_DATA)' '@Consumes(MediaType.APPLICATION_FORM_URLENCODED)'. Offending method is "
+ "'%s#%s'",
currentMethodInfo.declaringClass().name(), currentMethodInfo));
}
}
}
Type methodContextReturnTypeOrReturnType = methodContext.containsKey(METHOD_CONTEXT_CUSTOM_RETURN_TYPE_KEY)
? (Type) methodContext.get(METHOD_CONTEXT_CUSTOM_RETURN_TYPE_KEY)
: currentMethodInfo.returnType();
if (REST_RESPONSE.equals(methodContextReturnTypeOrReturnType.name())
&& (methodContextReturnTypeOrReturnType.kind() == Kind.CLASS)) {
log.warnf("Method '%s' of Resource class '%s' returns RestResponse but does not declare a generic type. "
+ "It is strongly advised to define the generic type otherwise the behavior could be unpredictable",
currentMethodInfo, currentMethodInfo.declaringClass().name());
}
Type nonAsyncReturnType = getNonAsyncReturnType(methodContextReturnTypeOrReturnType);
addWriterForType(additionalWriters, nonAsyncReturnType);View on GitHub (pinned to e1c734241f)
Solutions
- Add or correct @Consumes on the method: @Consumes(MediaType.MULTIPART_FORM_DATA) for file/multipart uploads or @Consumes(MediaType.APPLICATION_FORM_URLENCODED) for plain form posts
- Remove @FormParam/@RestForm parameters if the method really consumes JSON or another content type
- Check for inherited/class-level @Consumes annotations that restrict the allowed media types
Example fix
// before
@POST
public String submit(@RestForm String name) { ... }
// after
@POST
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public String submit(@RestForm String name) { ... } Defensive patterns
Strategy: validation
Validate before calling
Consumes consumes = MyResource.class.getMethod("submit", String.class)
.getAnnotation(Consumes.class);
boolean ok = consumes != null && java.util.Arrays.stream(consumes.value()).anyMatch(
mt -> mt.equals(MediaType.MULTIPART_FORM_DATA) || mt.equals(MediaType.APPLICATION_FORM_URLENCODED));
if (!ok) throw new IllegalStateException("Form-param method must consume multipart/form-data or application/x-www-form-urlencoded"); Prevention
- Always pair @RestForm/@FormParam methods with an explicit method-level @Consumes
- Remember class-level @Consumes applies when method-level is absent — audit it
- Use a code-review checklist item: form param => form/multipart consumes
- Run a quick quarkus:dev build locally before pushing; this error surfaces at deployment
When it happens
Trigger: A resource method has @FormParam/@RestForm parameters but its @Consumes annotation lists a media type other than MULTIPART_FORM_DATA or APPLICATION_FORM_URLENCODED (e.g. application/json), or omits @Consumes entirely while a class-level @Consumes application/json applies.
Common situations: Forgetting @Consumes when adding form params; a class-level @Consumes(MediaType.APPLICATION_JSON) overriding expectations; form params left over after changing a method from form submission to JSON body handling.
Related errors
- '@FormParam' and '@RestForm' cannot be used in a resource me
- Parameter: ${i} of the constructor of class '${resourceDotNa
- Unable to load handled exception type ${i.getProvidedType()}
- Endpoints that produce a Multipart result can only be used o
- Failed to process method '%s#%s'. Reason: %s
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/a07056a089920ce7.
Report an issue: GitHub.