OpenFeign/feign · error · HttpMessageNotReadableException

Content-Type is missing.

Error message

Content-Type is missing.

What it means

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.

Solutions

  1. Ensure the server/response includes Content-Type: multipart/mixed (or form-data) with a boundary parameter
  2. Check proxies/interceptors are not stripping the Content-Type header
  3. Verify the converter is only applied to messages that are actually multipart

Example fix

// before
response.headers(new HttpHeaders()); // no Content-Type
// after
HttpHeaders h = new HttpHeaders();
h.setContentType(MediaType.parseMediaType("multipart/mixed; boundary=--boundary"));
response.headers(h);
Defensive patterns

Strategy: try-catch

Validate before calling

if (message.getHeaders() == null || message.getHeaders().getContentType() == null) {
  throw new IllegalStateException("Content-Type missing on multipart response");
}

Try / catch

try {
  MultipartFile[] files = reader.read(type, message);
} catch (HttpMessageNotReadableException e) {
  // missing Content-Type; reject or re-request with correct media type
}

Prevention

When it happens

Trigger: Decoding a multipart response where headers exist but getContentType() returns null — i.e. no Content-Type header was set on the message.

Common situations: 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.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


AI-assisted analysis of OpenFeign/feign@e2a1e27560 (2026-09-10). Data as JSON: /api/errors/b79f91570f1c9aa1. Report an issue: GitHub.

Appendix: source

Thrown at form-spring/src/main/java/feign/form/spring/converter/SpringManyMultipartFilesReader.java:94

    return false; // Class NOT meant for writing multipart/form-data HTTP bodies
  }

  @Override
  protected boolean supports(Class<?> clazz) {
    return MultipartFile[].class == clazz;
  }

  @Override
  protected MultipartFile[] readInternal(
      Class<? extends MultipartFile[]> clazz, HttpInputMessage inputMessage) throws IOException {
    val headers = inputMessage.getHeaders();
    if (headers == null) {
      throw new HttpMessageNotReadableException("There are no headers at all.", inputMessage);
    }

    MediaType contentType = headers.getContentType();
    if (contentType == null) {
      throw new HttpMessageNotReadableException("Content-Type is missing.", inputMessage);
    }

    val boundaryBytes = getMultiPartBoundary(contentType);
    MultipartStream multipartStream =
        new MultipartStream(inputMessage.getBody(), boundaryBytes, bufSize, null);

    val multiparts = new LinkedList<ByteArrayMultipartFile>();
    for (boolean nextPart = multipartStream.skipPreamble();
        nextPart;
        nextPart = multipartStream.readBoundary()) {
      ByteArrayMultipartFile multiPart;
      try {
        multiPart = readMultiPart(multipartStream);
      } catch (Exception e) {
        throw new HttpMessageNotReadableException(
            "Multipart body could not be read.", e, inputMessage);
      }
      multiparts.add(multiPart);

View on GitHub (pinned to e2a1e27560)