eclipse-vertx/vert.x · error · IllegalStateException
Request method must be one of POST, PUT, PATCH or DELETE to
Error message
Request method must be one of POST, PUT, PATCH or DELETE to decode a multipart request
What it means
Thrown by Http1ServerRequest.setExpectMultipart(true) when the HTTP method is not one of POST, PUT, PATCH or DELETE (checked by HttpUtils.isValidMultipartMethod). Multipart body decoding is only meaningful for methods that can carry a body.
Source
Thrown at vertx-core/src/main/java/io/vertx/core/http/impl/http1/Http1ServerRequest.java:483
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;
}
}
@Override
public synchronized boolean isExpectMultipart() {
return expectMultipart;
}View on GitHub (pinned to fb308bd8c3)
Solutions
- Ensure the client uses POST/PUT/PATCH/DELETE for the upload
- Restrict the route to body-carrying methods, or check request.method() before enabling multipart
- Move setExpectMultipart(true) into the POST/PUT handler only
Example fix
// before
request.setExpectMultipart(true);
// after
if (request.method() == HttpMethod.POST || request.method() == HttpMethod.PUT) {
request.setExpectMultipart(true);
} Defensive patterns
Strategy: validation
Validate before calling
HttpMethod m = request.method();
if (m == HttpMethod.POST || m == HttpMethod.PUT || m == HttpMethod.PATCH || m == HttpMethod.DELETE) {
request.setExpectMultipart(true);
} Try / catch
try { request.setExpectMultipart(true); } catch (IllegalStateException e) { response.setStatusCode(405).end(); } Prevention
- Restrict upload routes to POST/PUT/PATCH/DELETE
- Check the method before enabling multipart
- Use router methods that limit allowed HTTP methods
When it happens
Trigger: Calling request.setExpectMultipart(true) inside handlers for GET, HEAD, OPTIONS, TRACE or CONNECT requests, e.g. a shared handler registered on multiple routes including GET.
Common situations: A catch-all route handler that enables multipart regardless of method; routing an upload endpoint with the wrong HTTP method from the client.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Request method must be one of POST, PUT, PATCH or DELETE to
- Request must have a content-type header to decode a multipar
- Request must have a valid content-type header to decode a mu
- Multipart form requires multipart/form-data content type ins
- Request must have a content-type header to decode a multipar
AI-assisted analysis of eclipse-vertx/vert.x@fb308bd8c3 (2026-09-06).
Data as JSON: /api/errors/522a107b66f9fc83.
Report an issue: GitHub.