gofiber/fiber · error
failed to close multipart writer
Error message
failed to close multipart writer: %w
What it means
After all form fields and files are written, parserRequestBodyFile calls mw.Close() to emit the trailing multipart boundary. This wraps a failure of that Close, meaning the underlying body writer reported an error finalizing the multipart payload, so the request body would be malformed if sent.
Solutions
- Check the wrapped cause — it identifies whether the buffer, pipe, or streaming writer failed.
- Avoid mutating or closing the request's RawRequest concurrently with sending.
- If streaming a large upload, ensure the body writer's lifecycle outlives mw.Close().
Defensive patterns
Strategy: try-catch
Try / catch
if err := c.Post(url, req); err != nil {
if strings.Contains(err.Error(), "failed to close multipart writer") {
// body writer failed finalizing multipart; do not retry the same body
}
} Prevention
- Do not close or mutate the request's RawRequest body concurrently with the send.
- Keep the BodyWriter alive until the request completes.
- For streaming bodies, ensure the producer outlives mw.Close().
When it happens
Trigger: The request's BodyWriter (a bytes.Buffer or pipe backing the raw request) returns an error on the final write; an injected streaming body writer that fails; memory exhaustion while buffering a very large upload.
Common situations: A custom BodyWriter (e.g. an http.Pipe) whose write side errored; content-length/size mismatch in a streaming upload; the connection or underlying buffer was closed early by another goroutine.
Related errors
- write formdata error
- boundary generation
- failed to copy file data
- file: failed to open file
- set boundary error
AI-assisted analysis of gofiber/fiber@a105acad6c (2026-08-11).
Data as JSON: /api/errors/fd9b61a6587423ae.
Report an issue: GitHub.
Appendix: source
Thrown at client/hooks.go:250
return nil
}
// parserRequestBodyFile handles the case where the request contains files to be uploaded.
func parserRequestBodyFile(req *Request) error {
mw := multipart.NewWriter(req.RawRequest.BodyWriter())
if err := mw.SetBoundary(req.boundary); err != nil {
return fmt.Errorf("set boundary error: %w", err)
}
if err := writeMultipartBody(mw, req); err != nil {
mw.Close() //nolint:errcheck // the body write already failed; surface that error instead
return err
}
// Close writes the trailing boundary; if it fails the multipart body is
// incomplete, so surface the error instead of sending a malformed request.
if err := mw.Close(); err != nil {
return fmt.Errorf("failed to close multipart writer: %w", err)
}
return nil
}
// writeMultipartBody writes the form fields and files of req to mw.
func writeMultipartBody(mw *multipart.Writer, req *Request) error {
// Add form data.
var err error
for key, value := range req.formData.All() {
err = mw.WriteField(utils.UnsafeString(key), utils.UnsafeString(value))
if err != nil {
break
}
}
if err != nil {
return fmt.Errorf("write formdata error: %w", err)
}View on GitHub (pinned to a105acad6c)