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

  1. Check the wrapped cause — it identifies whether the buffer, pipe, or streaming writer failed.
  2. Avoid mutating or closing the request's RawRequest concurrently with sending.
  3. 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

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


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)