eclipse-vertx/vert.x · error · IllegalStateException
Sending form requires multipart/form-data or " + HttpHeaders
Error message
Sending form requires multipart/form-data or " + HttpHeaders.APPLICATION_X_WWW_FORM_URLENCODED + " content type instead of " + contentType
What it means
Vert.x throws this IllegalStateException when send() is called with a form body but the Content-Type header is neither multipart/form-data nor application/x-www-form-urlencoded. The client needs to know which form encoding to use and cannot serialize the form otherwise.
Source
Thrown at vertx-core/src/main/java/io/vertx/core/http/impl/HttpClientRequestImpl.java:315
HttpPostRequestEncoder.EncoderMode encoderMode = multipartMixed ? HttpPostRequestEncoder.EncoderMode.RFC1738 : HttpPostRequestEncoder.EncoderMode.HTML5;
ClientMultipartFormUpload form;
try {
boolean multipart;
if (contentType == null) {
multipart = impl.isMultipart();
contentType = multipart ? HttpHeaders.MULTIPART_FORM_DATA.toString() : HttpHeaders.APPLICATION_X_WWW_FORM_URLENCODED.toString();
putHeader(HttpHeaderNames.CONTENT_TYPE, contentType);
} else {
if (contentType.equalsIgnoreCase(HttpHeaders.APPLICATION_X_WWW_FORM_URLENCODED.toString())) {
if (impl.isMultipart()) {
throw new IllegalStateException("Multipart form requires multipart/form-data content type instead of "
+ HttpHeaders.APPLICATION_X_WWW_FORM_URLENCODED);
}
multipart = false;
} else if (contentType.equalsIgnoreCase(HttpHeaders.MULTIPART_FORM_DATA.toString())) {
multipart = true;
} else {
throw new IllegalStateException("Sending form requires multipart/form-data or "
+ HttpHeaders.APPLICATION_X_WWW_FORM_URLENCODED + " content type instead of " + contentType);
}
}
form = new ClientMultipartFormUpload(context, impl, multipart, encoderMode);
} catch (Exception e) {
reset(0, e);
return response();
}
for (Map.Entry<String, String> header : form.headers()) {
if (header.getKey().equalsIgnoreCase(CONTENT_LENGTH.toString())) {
if (Integer.parseInt(header.getValue()) < 0) {
// Bug ?
continue;
}
}
putHeader(header.getKey(), header.getValue());
}
return send(form);View on GitHub (pinned to fb308bd8c3)
Solutions
- Remove the custom Content-Type header so Vert.x chooses the correct form encoding automatically
- Set Content-Type to multipart/form-data or application/x-www-form-urlencoded explicitly
- If you need a JSON body, replace the form with a JSON-serialized buffer instead of setting a form
Example fix
// before request.putHeader(HttpHeaders.CONTENT_TYPE, "application/json"); request.setForm(form); // after request.setForm(form); // content type set automatically, or: request.putHeader(HttpHeaders.CONTENT_TYPE, HttpHeaders.APPLICATION_X_WWW_FORM_URLENCODED);
Defensive patterns
Strategy: validation
Validate before calling
String ct = request.headers().get(HttpHeaders.CONTENT_TYPE);
if (ct != null && !HttpHeaders.MULTIPART_FORM_DATA.contentEqualsIgnoreCase(ct)
&& !HttpHeaders.APPLICATION_X_WWW_FORM_URLENCODED.contentEqualsIgnoreCase(ct)) {
request.headers().remove(HttpHeaders.CONTENT_TYPE);
} Try / catch
try {
request.send();
} catch (IllegalStateException e) {
if (e.getMessage().startsWith("Sending form requires")) {
request.headers().remove(HttpHeaders.CONTENT_TYPE);
request.send();
} else { throw e; }
} Prevention
- Never hardcode Content-Type alongside form APIs
- Keep form submission code in a single reviewed path
- Test form requests against a real endpoint to catch header conflicts
When it happens
Trigger: Calling send() on a request with a form or multipart form set while the Content-Type header was overwritten with some other value, e.g. application/json, text/plain, or a vendor content type.
Common situations: Global header interceptors setting Content-Type: application/json on every request including form submissions; copy-pasted code that sets a content type incompatible with the form; manual header construction typos.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- 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
- Request must have a valid content-type header to decode a mu
- Cannot have pipelining with no keep alive
AI-assisted analysis of eclipse-vertx/vert.x@fb308bd8c3 (2026-09-06).
Data as JSON: /api/errors/4123ab82f38102a7.
Report an issue: GitHub.