{"record":{"id":"ae69ddc3cf0e804e","repo":"OpenFeign/feign","slug":"output-closing-error","errorCode":null,"errorMessage":"Output closing error","messagePattern":"Output closing error","errorType":"exception","errorClass":"EncodeException","httpStatus":null,"severity":"error","filePath":"form/src/main/java/feign/form/MultipartFormContentProcessor.java","lineNumber":111,"sourceCode":"      val contentTypeHeaderValue =\n          new StringBuilder()\n              .append(getSupportedContentType().getHeader())\n              .append(\"; charset=\")\n              .append(charset.name())\n              .append(\"; boundary=\")\n              .append(boundary)\n              .toString();\n\n      template.header(CONTENT_TYPE_HEADER, Collections.<String>emptyList()); // reset header\n      template.header(CONTENT_TYPE_HEADER, contentTypeHeaderValue);\n\n      // Feign's clients try to determine binary/string content by charset presence\n      // so, I set it to null (in spite of availability charset) for backward\n      // compatibility.\n      val bytes = output.toByteArray();\n      template.body(bytes, null);\n    } catch (IOException ex) {\n      throw new EncodeException(\"Output closing error\", ex);\n    }\n  }\n\n  @Override\n  public ContentType getSupportedContentType() {\n    return MULTIPART;\n  }\n\n  /**\n   * Adds {@link Writer} instance in runtime.\n   *\n   * @param writer additional writer.\n   */\n  public final void addWriter(Writer writer) {\n    writers.add(writer);\n  }\n\n  /**","sourceCodeStart":93,"sourceCodeEnd":129,"githubUrl":"https://github.com/OpenFeign/feign/blob/e2a1e27560a1e68840c34f031afca88b36096e30/form/src/main/java/feign/form/MultipartFormContentProcessor.java#L93-L129","documentation":"MultipartFormContentProcessor writes all parts into an internal ByteArrayOutputStream; if closing/flushing that stream raises IOException while processing the multipart template, the IOException is wrapped in an EncodeException with message 'Output closing error'.","triggerScenarios":"process() called (e.g. while generating a boundary and writing parts) and an IOException occurs on the underlying output stream — e.g. a part writer failing mid-stream, memory/IO pressure on the ByteArrayOutputStream path.","commonSituations":"Encoding a multipart request where one of the registered writers throws an IOException (often surfacing here rather than at the writer), or an interrupted write of a large file body.","solutions":["Inspect the wrapped cause (EncodeException.getCause()) to find the actual failing writer/file","Verify all files being encoded are readable and not deleted/concurrently modified","Catch EncodeException around Feign encoding calls and log the cause","Update feign-form if an older version had stream-handling bugs"],"exampleFix":"// before\ntry {\n  feignClient.upload(file);\n} catch (EncodeException e) {\n  log.error(\"encode failed\");\n}\n// after\ntry {\n  feignClient.upload(file);\n} catch (EncodeException e) {\n  log.error(\"encode failed: \" + e.getCause(), e); // see real IOException\n}","handlingStrategy":"try-catch","validationCode":"for (File f : files) {\n  if (!f.canRead()) throw new IllegalStateException(\"unreadable file: \" + f);\n}","typeGuard":null,"tryCatchPattern":"try {\n  client.upload(file);\n} catch (EncodeException e) {\n  log.error(\"multipart encoding failed\", e.getCause());\n  throw new UncheckedIOException((IOException) e.getCause());\n}","preventionTips":["Ensure source files are readable and not concurrently modified during encoding","Catch EncodeException at the call boundary and inspect getCause()","Keep feign-form updated to benefit from stream-handling fixes"],"tags":["feign","multipart","io-exception","encoder"],"backgroundTag":"file-write-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"}