eclipse-vertx/vert.x · error · IllegalStateException

Multipart form requires multipart/form-data content type ins

Error message

Multipart form requires multipart/form-data content type instead of " + HttpHeaders.APPLICATION_X_WWW_FORM_URLENCODED

What it means

Vert.x throws this IllegalStateException when you pass a MultiPartForm to HttpClientRequest.send() but the request's Content-Type header is set to application/x-www-form-urlencoded. A multipart form body (with boundaries) is not encoded in the URL-encoded format, so sending it would produce a malformed request body.

Source

Thrown at vertx-core/src/main/java/io/vertx/core/http/impl/HttpClientRequestImpl.java:308

  }

  @Override
  public Future<HttpClientResponse> send(ClientForm body) {
    ClientMultipartFormImpl impl = (ClientMultipartFormImpl) body;
    String contentType = headers != null ? headers.get(HttpHeaders.CONTENT_TYPE) : null;
    boolean multipartMixed = impl.mixed();
    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) {

View on GitHub (pinned to fb308bd8c3)

Solutions

  1. Remove the explicit putHeader/setContentType of application/x-www-form-urlencoded and let Vert.x set multipart/form-data automatically when a multipart form is present
  2. Set the Content-Type to multipart/form-data (or use HttpHeaders.MULTIPART_FORM_DATA) instead of application/x-www-form-urlencoded
  3. Use a plain (non-multipart) Form instead of MultiPartForm if you actually intend to send urlencoded data

Example fix

// before
request.putHeader(HttpHeaders.CONTENT_TYPE, HttpHeaders.APPLICATION_X_WWW_FORM_URLENCODED);
request.setMultipartForm(form);
// after
request.setMultipartForm(form); // Vert.x sets multipart/form-data automatically
Defensive patterns

Strategy: validation

Validate before calling

if (form instanceof MultiPartForm && HttpHeaders.APPLICATION_X_WWW_FORM_URLENCODED.contentEqualsIgnoreCase(request.headers().get(HttpHeaders.CONTENT_TYPE))) {
  request.headers().remove(HttpHeaders.CONTENT_TYPE);
}

Type guard

boolean isMultipartCompatible(String contentType) {
  return contentType == null
    || HttpHeaders.MULTIPART_FORM_DATA.contentEqualsIgnoreCase(contentType)
    || HttpHeaders.APPLICATION_X_WWW_FORM_URLENCODED.contentEqualsIgnoreCase(contentType);
}

Prevention

When it happens

Trigger: Calling send() on a request whose form is a MultiPartForm (e.g. set via HttpClientRequest.setMultipartForm or form upload mode) while the Content-Type header was explicitly set to application/x-www-form-urlencoded, typically via putHeader("Content-Type", ...) or setContentType before send.

Common situations: File-upload code that copies a Content-Type header from a plain form example; frameworks or interceptors that force application/x-www-form-urlencoded on all POSTs; migrating code from urlencoded forms to multipart uploads without updating the header.

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


AI-assisted analysis of eclipse-vertx/vert.x@fb308bd8c3 (2026-09-06). Data as JSON: /api/errors/ba8bbae16bf6ff7e. Report an issue: GitHub.