{"record":{"id":"b79f91570f1c9aa1","repo":"OpenFeign/feign","slug":"content-type-is-missing","errorCode":null,"errorMessage":"Content-Type is missing.","messagePattern":"Content-Type is missing\\.","errorType":"exception","errorClass":"HttpMessageNotReadableException","httpStatus":null,"severity":"error","filePath":"form-spring/src/main/java/feign/form/spring/converter/SpringManyMultipartFilesReader.java","lineNumber":94,"sourceCode":"    return false; // Class NOT meant for writing multipart/form-data HTTP bodies\n  }\n\n  @Override\n  protected boolean supports(Class<?> clazz) {\n    return MultipartFile[].class == clazz;\n  }\n\n  @Override\n  protected MultipartFile[] readInternal(\n      Class<? extends MultipartFile[]> clazz, HttpInputMessage inputMessage) throws IOException {\n    val headers = inputMessage.getHeaders();\n    if (headers == null) {\n      throw new HttpMessageNotReadableException(\"There are no headers at all.\", inputMessage);\n    }\n\n    MediaType contentType = headers.getContentType();\n    if (contentType == null) {\n      throw new HttpMessageNotReadableException(\"Content-Type is missing.\", inputMessage);\n    }\n\n    val boundaryBytes = getMultiPartBoundary(contentType);\n    MultipartStream multipartStream =\n        new MultipartStream(inputMessage.getBody(), boundaryBytes, bufSize, null);\n\n    val multiparts = new LinkedList<ByteArrayMultipartFile>();\n    for (boolean nextPart = multipartStream.skipPreamble();\n        nextPart;\n        nextPart = multipartStream.readBoundary()) {\n      ByteArrayMultipartFile multiPart;\n      try {\n        multiPart = readMultiPart(multipartStream);\n      } catch (Exception e) {\n        throw new HttpMessageNotReadableException(\n            \"Multipart body could not be read.\", e, inputMessage);\n      }\n      multiparts.add(multiPart);","sourceCodeStart":76,"sourceCodeEnd":112,"githubUrl":"https://github.com/OpenFeign/feign/blob/e2a1e27560a1e68840c34f031afca88b36096e30/form-spring/src/main/java/feign/form/spring/converter/SpringManyMultipartFilesReader.java#L76-L112","documentation":"SpringManyMultipartFilesReader.readInternal() throws HttpMessageNotReadableException when the Content-Type header is absent, since the multipart boundary required by MultipartStream can only be extracted from the Content-Type.","triggerScenarios":"Decoding a multipart response where headers exist but getContentType() returns null — i.e. no Content-Type header was set on the message.","commonSituations":"Server responses missing Content-Type; custom clients or proxies stripping the header; wrong Accept/Content-Type negotiation causing a non-multipart body to be routed to this converter.","solutions":["Ensure the server/response includes Content-Type: multipart/mixed (or form-data) with a boundary parameter","Check proxies/interceptors are not stripping the Content-Type header","Verify the converter is only applied to messages that are actually multipart"],"exampleFix":"// before\nresponse.headers(new HttpHeaders()); // no Content-Type\n// after\nHttpHeaders h = new HttpHeaders();\nh.setContentType(MediaType.parseMediaType(\"multipart/mixed; boundary=--boundary\"));\nresponse.headers(h);","handlingStrategy":"try-catch","validationCode":"if (message.getHeaders() == null || message.getHeaders().getContentType() == null) {\n  throw new IllegalStateException(\"Content-Type missing on multipart response\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  MultipartFile[] files = reader.read(type, message);\n} catch (HttpMessageNotReadableException e) {\n  // missing Content-Type; reject or re-request with correct media type\n}","preventionTips":["Verify servers return Content-Type with a boundary for multipart endpoints","Check proxies/interceptors do not strip Content-Type","Only register this converter for multipart media types"],"tags":["multipart","deserialization","content-type","http-headers"],"backgroundTag":"missing-required-config-field","analyzedSha":"e2a1e27560a1e68840c34f031afca88b36096e30","analyzedAt":"2026-09-10T12:37:37.238Z","contentChangedAt":"2026-09-10T12:37:37.238Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}