{"record":{"id":"45acf85a154ca204","repo":"eclipse-vertx/vert.x","slug":"request-must-have-a-content-type-header-to-decode","errorCode":null,"errorMessage":"Request must have a content-type header to decode a multipart request","messagePattern":"Request must have a content-type header to decode a multipart request","errorType":"validation","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"vertx-core/src/main/java/io/vertx/core/http/impl/HttpServerRequestImpl.java","lineNumber":415,"sourceCode":"      return absoluteURI;\n    }\n  }\n\n  @Override\n  public Future<NetSocket> toNetSocket() {\n    return response.netSocket(this);\n  }\n\n  @Override\n  public HttpServerRequest setExpectMultipart(boolean expect) {\n    synchronized (connection) {\n      checkEnded();\n      expectMultipart = expect;\n      if (expect) {\n        if (postRequestDecoder == null) {\n          String contentType = headersMap.get(HttpHeaderNames.CONTENT_TYPE);\n          if (contentType == null) {\n            throw new IllegalStateException(\"Request must have a content-type header to decode a multipart request\");\n          }\n          if (!HttpUtils.isValidMultipartContentType(contentType)) {\n            throw new IllegalStateException(\"Request must have a valid content-type header to decode a multipart request\");\n          }\n          if (!HttpUtils.isValidMultipartMethod(method.toNetty())) {\n            throw new IllegalStateException(\"Request method must be one of POST, PUT, PATCH or DELETE to decode a multipart request\");\n          }\n          HttpRequest req = new DefaultHttpRequest(\n            io.netty.handler.codec.http.HttpVersion.HTTP_1_1,\n            method.toNetty(),\n            uri);\n          req.headers().add(HttpHeaderNames.CONTENT_TYPE, contentType);\n          NettyFileUploadDataFactory factory = new NettyFileUploadDataFactory(context, this, () -> uploadHandler);\n          factory.setMaxLimit(maxFormAttributeSize);\n          postRequestDecoder = new HttpPostRequestDecoder(factory, req, HttpConstants.DEFAULT_CHARSET, maxFormFields, maxFormBufferedBytes);\n        }\n      } else {\n        postRequestDecoder = null;","sourceCodeStart":397,"sourceCodeEnd":433,"githubUrl":"https://github.com/eclipse-vertx/vert.x/blob/fb308bd8c3f12c79f4ae89bef67fadf6c80d036e/vertx-core/src/main/java/io/vertx/core/http/impl/HttpServerRequestImpl.java#L397-L433","documentation":"setExpectMultipart(true) tells Vert.x to decode the request body as multipart/form-data using a Netty PostRequestDecoder. Multipart decoding requires the request to declare its content type; if the Content-Type header is absent, the decoder cannot know the body format, so an IllegalStateException is thrown.","triggerScenarios":"Calling request.setExpectMultipart(true) on an incoming request that has no Content-Type header at all.","commonSituations":"Clients (curl, custom HTTP clients, tests) sending a multipart-looking body without setting Content-Type; proxies stripping headers; requests where the body was sent raw without headers.","solutions":["Ensure the HTTP client sends a Content-Type header, e.g. multipart/form-data; boundary=...","Validate the header server-side before calling setExpectMultipart(true)","If the request is legitimately not multipart, do not enable multipart expectation for it"],"exampleFix":"// before\nrequest.setExpectMultipart(true); // throws when no Content-Type\n\n// after\nif (request.getHeader(\"Content-Type\") != null) {\n  request.setExpectMultipart(true);\n} else {\n  request.response().setStatusCode(400).end(\"Content-Type header required\");\n}","handlingStrategy":"validation","validationCode":"if (request.getHeader(HttpHeaders.CONTENT_TYPE) == null) {\n  request.response().setStatusCode(400).end();\n  return;\n}\nrequest.setExpectMultipart(true);","typeGuard":null,"tryCatchPattern":"try {\n  request.setExpectMultipart(true);\n} catch (IllegalStateException e) {\n  // missing content-type; reject request\n}","preventionTips":["Fix clients to always send Content-Type on POST/PUT bodies","Check the header before enabling multipart","Reject requests lacking Content-Type early"],"tags":["http","multipart","content-type","validation"],"backgroundTag":"missing-required-argument","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"}