eclipse-vertx/vert.x · error · IllegalStateException
Request must have a content-type header to decode a multipar
Error message
Request must have a content-type header to decode a multipart request
What it means
Thrown by Http1ServerRequest.setExpectMultipart(true) when the request has no Content-Type header. Vert.x needs the content type to decide how to decode the body into multipart/form-data parts via HttpPostRequestDecoder; without it, multipart decoding cannot be configured.
Source
Thrown at vertx-core/src/main/java/io/vertx/core/http/impl/http1/Http1ServerRequest.java:477
EmptyHttpHeaders.INSTANCE
);
conn.createWebSocket(this, promise);
}
});
// In case we were paused
resume();
}
@Override
public HttpServerRequest setExpectMultipart(boolean expect) {
synchronized (conn) {
checkEnded();
expectMultipart = expect;
if (expect) {
if (decoder == null) {
String contentType = request.headers().get(HttpHeaderNames.CONTENT_TYPE);
if (contentType == null) {
throw new IllegalStateException("Request must have a content-type header to decode a multipart request");
}
if (!HttpUtils.isValidMultipartContentType(contentType)) {
throw new IllegalStateException("Request must have a valid content-type header to decode a multipart request");
}
if (!HttpUtils.isValidMultipartMethod(request.method())) {
throw new IllegalStateException("Request method must be one of POST, PUT, PATCH or DELETE to decode a multipart request");
}
NettyFileUploadDataFactory factory = new NettyFileUploadDataFactory(context, this, () -> uploadHandler);
factory.setMaxLimit(conn.maxFormAttributeSize());
int maxFields = conn.maxFormFields();
int maxBufferedBytes = conn.maxFormBufferedBytes();
decoder = new HttpPostRequestDecoder(factory, request, HttpConstants.DEFAULT_CHARSET, maxFields, maxBufferedBytes);
}
} else {
decoder = null;
}
return this;
}View on GitHub (pinned to fb308bd8c3)
Solutions
- Set the Content-Type header on the client request, e.g. 'multipart/form-data; boundary=----boundary'
- Check the client actually performs a multipart upload rather than sending a raw body without headers
- If the body may lack the header, guard the call: only call setExpectMultipart(true) when request.getHeader("Content-Type") != null
Example fix
// before curl -X POST http://host/upload --data-binary @file.bin // after curl -X POST http://host/upload -H "Content-Type: multipart/form-data; boundary=XYZ" -F file=@file.bin
Defensive patterns
Strategy: validation
Validate before calling
if (request.getHeader(HttpHeaderNames.CONTENT_TYPE) != null) {
request.setExpectMultipart(true);
} Try / catch
try { request.setExpectMultipart(true); } catch (IllegalStateException e) { /* no content-type: handle as plain body */ } Prevention
- Always send Content-Type on uploads
- Set the header before the body is sent
- Validate client headers in integration tests
When it happens
Trigger: Calling request.setExpectMultipart(true) on an incoming HTTP/1.x request whose headers do not include a Content-Type header (e.g. a POST with no Content-Type, or a request built manually by a test client).
Common situations: Clients (curl, custom HTTP clients, raw sockets) omitting Content-Type on form uploads; proxies stripping the header; unit tests constructing bare POST requests.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- Request must have a valid content-type header to decode a mu
- Request method must be one of POST, PUT, PATCH or DELETE to
- Multipart form requires multipart/form-data content type ins
- Request must have a content-type header to decode a multipar
- Request must have a valid content-type header to decode a mu
AI-assisted analysis of eclipse-vertx/vert.x@fb308bd8c3 (2026-09-06).
Data as JSON: /api/errors/06530b127a67fef6.
Report an issue: GitHub.