quarkusio/quarkus · error · IllegalArgumentException
Multipart form upload expects an entity of type MultipartFor
Error message
Multipart form upload expects an entity of type MultipartForm or List<EntityPart>, got: " + entityObj
What it means
Before sending a multipart request, setMultipartHeadersAndPrepareBody expects the request entity to be either a QuarkusMultipartForm/MultipartForm or a List<EntityPart>. Any other entity object cannot be converted into a multipart body, so the handler throws IllegalArgumentException including the entity's actual value.
Source
Thrown at independent-projects/resteasy-reactive/client/runtime/src/main/java/org/jboss/resteasy/reactive/client/handlers/ClientSendRequestHandler.java:605
}
@SuppressWarnings("unchecked")
private QuarkusMultipartFormUpload setMultipartHeadersAndPrepareBody(HttpClientRequest httpClientRequest,
RestClientRequestContext state) throws Exception {
QuarkusMultipartForm multipartForm;
Object entityObj = state.getEntity().getEntity();
boolean entityPartList = false;
if (entityObj instanceof GenericEntity<?> ge) {
entityPartList = EntityPartImpl.isEntityPartList(ge.getType());
entityObj = ge.getEntity();
}
if (entityObj instanceof QuarkusMultipartForm) {
multipartForm = (QuarkusMultipartForm) entityObj;
} else if (entityObj instanceof List<?> list
&& (entityPartList || (!list.isEmpty() && list.get(0) instanceof EntityPart))) {
multipartForm = entityPartsToMultipartForm((List<EntityPart>) list);
} else {
throw new IllegalArgumentException(
"Multipart form upload expects an entity of type MultipartForm or List<EntityPart>, got: " + entityObj);
}
MultivaluedMap<String, String> headerMap = state.getRequestHeadersAsMap();
updateRequestHeadersFromConfig(state, headerMap);
multipartForm.preparePojos(state);
Object property = state.getConfiguration().getProperty(QuarkusRestClientProperties.MULTIPART_ENCODER_MODE);
PausableHttpPostRequestEncoder.EncoderMode mode = PausableHttpPostRequestEncoder.EncoderMode.RFC1738;
if (property != null) {
mode = (PausableHttpPostRequestEncoder.EncoderMode) property;
}
QuarkusMultipartFormUpload multipartFormUpload = new QuarkusMultipartFormUpload(Vertx.currentContext(), multipartForm,
true, maxChunkSize, mode);
httpClientRequest.setChunked(multipartFormUpload.isChunked());
setEntityRelatedHeaders(headerMap, state.getEntity());
// multipart has its own headers:View on GitHub (pinned to e1c734241f)
Solutions
- Pass a MultipartForm (e.g. MultipartForm.create().binaryFileUpload(...)) as the request entity.
- Or pass a List<EntityPart> built with EntityPart builder APIs.
- For proxied clients, declare the parameter with @MultipartForm so the client constructs the correct body type.
- Remove manual entity assignment that overrides the multipart body for multipart endpoints.
Example fix
// before
client.post(Map.of("file", data), FormData.class);
// after
MultipartForm form = MultipartForm.create()
.binaryFileUpload("file", "data.bin", path, "application/octet-stream");
client.post(form, Response.class); Defensive patterns
Strategy: type-guard
Validate before calling
if (!(entity instanceof MultipartForm) && !(entity instanceof List<?> l && (l.isEmpty() || l.get(0) instanceof EntityPart))) {
throw new IllegalArgumentException("Multipart entity must be MultipartForm or List<EntityPart>");
} Type guard
static boolean isValidMultipartEntity(Object e) {
return e instanceof MultipartForm
|| (e instanceof List<?> l && !l.isEmpty() && l.stream().allMatch(EntityPart.class::isInstance));
} Prevention
- Always send MultipartForm or List<EntityPart> for multipart endpoints
- Use @MultipartForm parameters in proxied clients
- Don't overwrite the entity on multipart request builders
When it happens
Trigger: Calling a client method declared with multipart form output but passing a mismatched entity: a raw POJO, a Map, a non-EntityPart List, or setting the entity manually via Invocation/REST-assured-style builders instead of using @MultipartForm-typed parameters or MultipartForm.
Common situations: Manually building requests with a POJO body while the endpoint expects multipart/form-data; generic client code reusing a JSON-entity call path for a multipart endpoint; List<T> where T is not EntityPart and the list is non-empty with entityPartList flag unset.
Related errors
- Multipart field name cannot be null
- Extra steps left over
- PartType annotation is only supported on fields and (setter/
- Primitive types are not supported for multipart response map
- Unsupported field type for multipart response mapping: " + t
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/31984c15b474d9a3.
Report an issue: GitHub.