valyala/fasthttp · error

cannot open form file %q (%q): %w

Error message

cannot open form file %q (%q): %w

What it means

fasthttp wraps the error returned by multipart.Writer.CreatePart (and, in the sibling message, part file Open) when writing a multipart/form-data request body. The quoted form field name, the original filename, and the underlying cause are embedded so the caller can identify which part failed. It signals the multipart writer could not emit the part header for this form file.

Source

Thrown at http.go:1251

	// marshal values
	for k, vv := range f.Value {
		for _, v := range vv {
			if err := mw.WriteField(k, v); err != nil {
				return fmt.Errorf("cannot write form field %q value %q: %w", k, v, err)
			}
		}
	}

	// marshal files
	for k, fvv := range f.File {
		for _, fv := range fvv {
			vw, err := mw.CreatePart(fv.Header)
			if err != nil {
				return fmt.Errorf("cannot create form file %q (%q): %w", k, fv.Filename, err)
			}
			fh, err := fv.Open()
			if err != nil {
				return fmt.Errorf("cannot open form file %q (%q): %w", k, fv.Filename, err)
			}
			if _, err = copyZeroAlloc(vw, fh); err != nil {
				_ = fh.Close()
				return fmt.Errorf("error when copying form file %q (%q): %w", k, fv.Filename, err)
			}
			if err = fh.Close(); err != nil {
				return fmt.Errorf("cannot close form file %q (%q): %w", k, fv.Filename, err)
			}
		}
	}

	if err := mw.Close(); err != nil {
		return fmt.Errorf("error when closing multipart form writer: %w", err)
	}

	return nil
}

View on GitHub (pinned to c96f600972)

Solutions

  1. Call req.Reset() (or use a fresh Request) before reusing it for another multipart request.
  2. Inspect the wrapped cause (%w) to fix the underlying CreatePart error.
  3. Verify the FormFile value passed to SetFormFile has a valid Filename and Open()-able content.
  4. Update fasthttp — multipart writer edge cases have been fixed over time.

Example fix

// before
req := acquireRequest()
req.SetFormFile(req.MultipartForm, "file", fh) // reused request
// after
req.Reset()
req.SetFormFile("file", fh)
if err := client.Do(req, resp); err != nil {
    log.Printf("multipart create part failed: %v", err)
}
Defensive patterns

Strategy: try-catch

Validate before calling

if req.MultipartForm != nil { for k, fv := range req.MultipartForm.File { if fv == nil { return fmt.Errorf("nil form file %s", k) } } }

Type guard

func validFormFile(f *multipart.FileHeader) bool { return f != nil && f.Filename != "" }

Try / catch

if err := client.Do(req, resp); err != nil {
    if strings.Contains(err.Error(), "cannot create form file") {
        req.Reset(); return retryWithFreshRequest()
    }
    return err
}

Prevention

When it happens

Trigger: Calling Request.SetFormFile / SetFormFileContent / SetFormFileCreate (or MultipartForm) and then writing the request, when the multipart writer's CreatePart fails while creating the part for form field k with filename fv.Filename — e.g. malformed part headers or writer already closed.

Common situations: Reusing a Request whose previous multipart write already closed the writer; corrupt MultipartForm state after reuse without Reset; very large form value headers; bugs in custom FormFile implementations returning bad headers.

Related errors


AI-assisted analysis of valyala/fasthttp@c96f600972 (2026-08-31). Data as JSON: /api/errors/4e7d459c3747b0d2. Report an issue: GitHub.