{"record":{"id":"4123ab82f38102a7","repo":"eclipse-vertx/vert.x","slug":"sending-form-requires-multipart-form-data-or-h","errorCode":null,"errorMessage":"Sending form requires multipart/form-data or \" + HttpHeaders.APPLICATION_X_WWW_FORM_URLENCODED + \" content type instead of \" + contentType","messagePattern":"Sending form requires multipart/form-data or \" \\+ HttpHeaders\\.APPLICATION_X_WWW_FORM_URLENCODED \\+ \" content type instead of \" \\+ contentType","errorType":"validation","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"vertx-core/src/main/java/io/vertx/core/http/impl/HttpClientRequestImpl.java","lineNumber":315,"sourceCode":"    HttpPostRequestEncoder.EncoderMode encoderMode = multipartMixed ? HttpPostRequestEncoder.EncoderMode.RFC1738 : HttpPostRequestEncoder.EncoderMode.HTML5;\n    ClientMultipartFormUpload form;\n    try {\n      boolean multipart;\n      if (contentType == null) {\n        multipart = impl.isMultipart();\n        contentType = multipart ? HttpHeaders.MULTIPART_FORM_DATA.toString() : HttpHeaders.APPLICATION_X_WWW_FORM_URLENCODED.toString();\n        putHeader(HttpHeaderNames.CONTENT_TYPE, contentType);\n      } else {\n        if (contentType.equalsIgnoreCase(HttpHeaders.APPLICATION_X_WWW_FORM_URLENCODED.toString())) {\n          if (impl.isMultipart()) {\n            throw new IllegalStateException(\"Multipart form requires multipart/form-data content type instead of \"\n              + HttpHeaders.APPLICATION_X_WWW_FORM_URLENCODED);\n          }\n          multipart = false;\n        } else if (contentType.equalsIgnoreCase(HttpHeaders.MULTIPART_FORM_DATA.toString())) {\n          multipart = true;\n        } else {\n          throw new IllegalStateException(\"Sending form requires multipart/form-data or \"\n            + HttpHeaders.APPLICATION_X_WWW_FORM_URLENCODED + \" content type instead of \" + contentType);\n        }\n      }\n      form = new ClientMultipartFormUpload(context, impl, multipart, encoderMode);\n    } catch (Exception e) {\n      reset(0, e);\n      return response();\n    }\n    for (Map.Entry<String, String> header : form.headers()) {\n      if (header.getKey().equalsIgnoreCase(CONTENT_LENGTH.toString())) {\n        if (Integer.parseInt(header.getValue()) < 0) {\n          // Bug ?\n          continue;\n        }\n      }\n      putHeader(header.getKey(), header.getValue());\n    }\n    return send(form);","sourceCodeStart":297,"sourceCodeEnd":333,"githubUrl":"https://github.com/eclipse-vertx/vert.x/blob/fb308bd8c3f12c79f4ae89bef67fadf6c80d036e/vertx-core/src/main/java/io/vertx/core/http/impl/HttpClientRequestImpl.java#L297-L333","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nrequest.putHeader(HttpHeaders.CONTENT_TYPE, \"application/json\");\nrequest.setForm(form);\n// after\nrequest.setForm(form); // content type set automatically, or:\nrequest.putHeader(HttpHeaders.CONTENT_TYPE, HttpHeaders.APPLICATION_X_WWW_FORM_URLENCODED);","handlingStrategy":"validation","validationCode":"String ct = request.headers().get(HttpHeaders.CONTENT_TYPE);\nif (ct != null && !HttpHeaders.MULTIPART_FORM_DATA.contentEqualsIgnoreCase(ct)\n    && !HttpHeaders.APPLICATION_X_WWW_FORM_URLENCODED.contentEqualsIgnoreCase(ct)) {\n  request.headers().remove(HttpHeaders.CONTENT_TYPE);\n}","typeGuard":null,"tryCatchPattern":"try {\n  request.send();\n} catch (IllegalStateException e) {\n  if (e.getMessage().startsWith(\"Sending form requires\")) {\n    request.headers().remove(HttpHeaders.CONTENT_TYPE);\n    request.send();\n  } else { throw e; }\n}","preventionTips":["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"],"tags":["http","form","content-type","client"],"backgroundTag":"invalid-argument-value","analyzedSha":"fb308bd8c3f12c79f4ae89bef67fadf6c80d036e","analyzedAt":"2026-09-06T11:37:12.241Z","contentChangedAt":"2026-09-06T11:37:12.241Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}