{"record":{"id":"6b0b2cda751e3dad","repo":"OpenFeign/feign","slug":"content-disposition-is-not-of-type-form-data","errorCode":null,"errorMessage":"Content-Disposition is not of type form-data.","messagePattern":"Content-Disposition is not of type form-data\\.","errorType":"exception","errorClass":"HttpMessageConversionException","httpStatus":null,"severity":"error","filePath":"form-spring/src/main/java/feign/form/spring/converter/SpringManyMultipartFilesReader.java","lineNumber":145,"sourceCode":"      throw new HttpMessageConversionException(\"Content-Type missing boundary information.\");\n    }\n    return boundaryString.getBytes(UTF_8);\n  }\n\n  private ByteArrayMultipartFile readMultiPart(MultipartStream multipartStream) throws IOException {\n    val multiPartHeaders =\n        splitIntoKeyValuePairs(\n            multipartStream.readHeaders(), NEWLINES_PATTERN, COLON_PATTERN, false);\n\n    val contentDisposition =\n        splitIntoKeyValuePairs(\n            multiPartHeaders.get(CONTENT_DISPOSITION),\n            SEMICOLON_PATTERN,\n            EQUALITY_SIGN_PATTERN,\n            true);\n\n    if (!contentDisposition.containsKey(\"form-data\")) {\n      throw new HttpMessageConversionException(\"Content-Disposition is not of type form-data.\");\n    }\n\n    val bodyStream = new ByteArrayOutputStream();\n    multipartStream.readBodyData(bodyStream);\n    return new ByteArrayMultipartFile(\n        contentDisposition.get(\"name\"),\n        contentDisposition.get(\"filename\"),\n        multiPartHeaders.get(CONTENT_TYPE),\n        bodyStream.toByteArray());\n  }\n\n  private Map<String, String> splitIntoKeyValuePairs(\n      String str,\n      Pattern entriesSeparatorPattern,\n      Pattern keyValueSeparatorPattern,\n      boolean unquoteValue) {\n    val keyValuePairs = new IgnoreKeyCaseMap();\n    if (StringUtils.hasLength(str)) {","sourceCodeStart":127,"sourceCodeEnd":163,"githubUrl":"https://github.com/OpenFeign/feign/blob/e2a1e27560a1e68840c34f031afca88b36096e30/form-spring/src/main/java/feign/form/spring/converter/SpringManyMultipartFilesReader.java#L127-L163","documentation":"Each part of a multipart/form-data body must carry Content-Disposition: form-data with name/filename parameters. If a part's Content-Disposition header cannot be parsed into something containing the form-data token, the reader rejects the part.","triggerScenarios":"readMultiPart encounters a part whose Content-Disposition header is missing, malformed, or declares another disposition type (e.g. attachment) — typically because the client generated the multipart body incorrectly.","commonSituations":"Hand-rolled multipart encoders writing wrong headers, proxies re-formatting headers, or body bytes misaligned so header parsing picks up garbage (often a symptom of a boundary mismatch).","solutions":["Fix the client's multipart encoder to emit 'Content-Disposition: form-data; name=\"...\"; filename=\"...\"' per part","If using feign-form, upgrade — it emits correct headers; verify the boundary matches the body so headers parse at correct offsets","Inspect raw bytes of the part headers to confirm they are not offset by a boundary mismatch"],"exampleFix":"// before (hand-built part)\noutput.write((\"Content-Disposition: attachment; name=\\\"file\\\"\\r\\n\").getBytes());\n// after\noutput.write((\"Content-Disposition: form-data; name=\\\"file\\\"; filename=\\\"a.txt\\\"\\r\\n\").getBytes());","handlingStrategy":"validation","validationCode":"// verify each part header on the sending side\n// Content-Disposition: form-data; name=\"file\"; filename=\"x.txt\"\nassert disposition.startsWith(\"form-data\") : \"part must be form-data\";","typeGuard":null,"tryCatchPattern":"try {\n  return readMultiPart(stream);\n} catch (HttpMessageConversionException e) {\n  throw new BadRequestException(\"malformed part: \" + e.getMessage());\n}","preventionTips":["Use a battle-tested multipart encoder (feign-form, Apache httpclient) instead of hand-building bodies","Keep boundary strings free of characters that appear in headers/bodies","Diff raw multipart bytes against a known-good sample when debugging"],"tags":["spring","multipart","content-disposition","malformed-body"],"backgroundTag":"schema-validation-failed","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"}