OpenFeign/feign · error · HttpMessageNotReadableException

There are no headers at all.

Error message

There are no headers at all.

What it means

SpringManyMultipartFilesReader.readInternal() throws HttpMessageNotReadableException when the HttpInputMessage has null headers, because the boundary needed to parse a multipart body is derived from the Content-Type header.

Solutions

  1. Ensure the Response/HttpInputMessage supplies non-null HttpHeaders
  2. Set a proper multipart Content-Type header (with boundary) on the response being decoded
  3. Fix custom Client or MockWebServer stubs to include headers

Example fix

// before
return new MockClientResponse(body); // headers missing
// after
return MockClientResponse.builder()
    .headers(HttpHeaders) // includes Content-Type: multipart/mixed; boundary=...
    .body(body)
    .build();
Defensive patterns

Strategy: validation

Validate before calling

HttpHeaders h = message.getHeaders();
if (h == null || h.getContentType() == null) {
  throw new IllegalStateException("Multipart response requires headers with Content-Type");
}

Try / catch

try {
  MultipartFile[] files = reader.read(type, message);
} catch (HttpMessageNotReadableException e) {
  // response lacked headers or Content-Type; handle malformed response
}

Prevention

When it happens

Trigger: Using the custom SpringManyMultipartFilesReader HttpMessageConverter to decode a response whose HttpInputMessage returns null getHeaders().

Common situations: Custom Client/Response implementations that build an HttpInputMessage without headers; mocking layers that omit headers; misconfigured converter usage on non-multipart messages.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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

Appendix: source

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

    this.bufSize = bufSize;
  }

  @Override
  protected boolean canWrite(MediaType mediaType) {
    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);

View on GitHub (pinned to e2a1e27560)