OpenFeign/feign · error · HttpMessageConversionException
Content-Type missing boundary information.
Error message
Content-Type missing boundary information.
What it means
The reader derives the multipart boundary from the boundary parameter of the Content-Type header. If the parameter is absent or empty it cannot delimit parts, so it throws HttpMessageConversionException.
Solutions
- Ensure the client sends Content-Type like multipart/form-data; boundary=<token> and does not override the encoder-generated header
- Let feign-form's encoder set the Content-Type instead of setting it manually in the interface/interceptors
- Check interceptors, filters, or gateways that replace the Content-Type header
Example fix
// before
@Headers("Content-Type: multipart/form-data")
@Post("/upload") Response upload(MultipartFile file);
// after
@Headers("Content-Type: multipart/form-data")
// and use SpringFormEncoder, which appends the boundary automatically
Feign.builder().encoder(new SpringFormEncoder())... Defensive patterns
Strategy: validation
Validate before calling
String ct = headers.getFirst("Content-Type");
boolean ok = ct != null && ct.matches("multipart/[\w-]+;.*boundary=.+");
if (!ok) throw new IllegalArgumentException("Content-Type missing boundary parameter"); Prevention
- Let the multipart encoder set Content-Type; do not hardcode it in @Headers or interceptors
- Audit filters/proxies that rewrite Content-Type headers
- Write an integration test asserting the outgoing Content-Type contains a boundary
When it happens
Trigger: readInternal/boundaryBytes is invoked on a request whose Content-Type is multipart/* but lacks the boundary parameter (or it is empty after unquoting).
Common situations: A client or intermediate proxy rewrites the Content-Type and strips the boundary; hand-built multipart requests forget the boundary parameter; code sets Content-Type manually instead of letting the encoder do it.
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
- Content-Type is missing.
- Multipart body could not be read.
- SpringManyMultipartFilesReader does not support writing to…
- Content-Disposition is not of type form-data.
- Unable to decode response ( ) ...
AI-assisted analysis of OpenFeign/feign@e2a1e27560 (2026-09-10).
Data as JSON: /api/errors/5bf982879b08779e.
Report an issue: GitHub.
Appendix: source
Thrown at form-spring/src/main/java/feign/form/spring/converter/SpringManyMultipartFilesReader.java:127
throw new HttpMessageNotReadableException(
"Multipart body could not be read.", e, inputMessage);
}
multiparts.add(multiPart);
}
return multiparts.toArray(new ByteArrayMultipartFile[0]);
}
@Override
protected void writeInternal(
MultipartFile[] byteArrayMultipartFiles, HttpOutputMessage outputMessage) {
throw new UnsupportedOperationException(
getClass().getSimpleName() + " does not support writing to HTTP body.");
}
private byte[] getMultiPartBoundary(MediaType contentType) {
val boundaryString = unquote(contentType.getParameter("boundary"));
if (StringUtils.hasLength(boundaryString) == false) {
throw new HttpMessageConversionException("Content-Type missing boundary information.");
}
return boundaryString.getBytes(UTF_8);
}
private ByteArrayMultipartFile readMultiPart(MultipartStream multipartStream) throws IOException {
val multiPartHeaders =
splitIntoKeyValuePairs(
multipartStream.readHeaders(), NEWLINES_PATTERN, COLON_PATTERN, false);
val contentDisposition =
splitIntoKeyValuePairs(
multiPartHeaders.get(CONTENT_DISPOSITION),
SEMICOLON_PATTERN,
EQUALITY_SIGN_PATTERN,
true);
if (!contentDisposition.containsKey("form-data")) {
throw new HttpMessageConversionException("Content-Disposition is not of type form-data.");View on GitHub (pinned to e2a1e27560)