valyala/fasthttp · error
form size must be greater than 0: given %d
Error message
form size must be greater than 0: given %d
What it means
fasthttp validates the declared Content-Length (size) before parsing an incoming multipart/form-data body in readMultipartForm; a non-positive size cannot yield any body. This is a server-side guard so it never passes a useless LimitReader to multipart.Reader.
Source
Thrown at http.go:1276
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
}
func readMultipartForm(r io.Reader, boundary string, size, maxInMemoryFileSize int) (*multipart.Form, error) {
// Do not care about memory allocations here, since they are tiny
// compared to multipart data (aka multi-MB files) usually sent
// in multipart/form-data requests.
if size <= 0 {
return nil, fmt.Errorf("form size must be greater than 0: given %d", size)
}
lr := io.LimitReader(r, int64(size))
mr := multipart.NewReader(lr, boundary)
f, err := mr.ReadForm(int64(maxInMemoryFileSize))
if err != nil {
return nil, fmt.Errorf("cannot read multipart/form-data body: %w", err)
}
return f, nil
}
// Reset clears request contents.
func (req *Request) Reset() {
req.userValues.Reset() // it should be at the top, since some values might implement io.Closer interface
if bodyPoolSizeLimit := int(atomic.LoadInt64(&requestBodyPoolSizeLimit)); bodyPoolSizeLimit >= 0 && req.body != nil {
req.ReleaseBody(bodyPoolSizeLimit)
}
req.Header.Reset()
req.resetSkipHeader()View on GitHub (pinned to c96f600972)
Solutions
- Fix the client to send a correct Content-Length with the multipart body.
- Server-side: reject requests without a body before calling ctx.FormFile/MultipartForm.
- If behind a proxy, configure it to preserve Content-Length for multipart posts.
- Send the multipart request via fasthttp's Request (which sets Content-Length automatically) instead of hand-rolled writers.
Example fix
// before (client)
req.Header.SetMethod("POST")
req.Header.Set("Content-Type", "multipart/form-data; boundary=x")
// body written without length
// after
req.SetFormFileContent("file", data, "a.txt") // fasthttp sets CL + boundary
client.Do(req, resp) Defensive patterns
Strategy: validation
Validate before calling
if ctx.Request.Header.ContentLength() <= 0 {
ctx.Error("multipart body required", fasthttp.StatusBadRequest)
return
} Type guard
func hasMultipartBody(ctx *fasthttp.RequestCtx) bool {
return ctx.Request.Header.ContentLength() > 0 &&
strings.HasPrefix(ctx.Request.Header.ContentType(), "multipart/form-data")
} Try / catch
form, err := ctx.MultipartForm()
if err != nil {
if strings.Contains(err.Error(), "form size must be greater than 0") {
ctx.Error("empty multipart body", fasthttp.StatusBadRequest)
return
}
return err
} Prevention
- Ensure clients send Content-Length with multipart posts
- Configure proxies/LBs to preserve Content-Length
- Reject zero-length multipart requests at the edge
When it happens
Trigger: Server request handling (ctx.FormFile / MultipartForm) on a request whose declared multipart size is <= 0 — e.g. Content-Length missing or 0 while a multipart Content-Type is present.
Common situations: Clients sending multipart bodies with chunked encoding or no Content-Length; proxies stripping Content-Length; load-generator clients that post empty multipart bodies.
Related errors
- fasthttp: request content-type has bad boundary or is not mu
- form boundary cannot be empty
- cert or key has not provided
- fasthttp: there is no uploaded file associated with the give
- fasthttp: too many connections per ip
AI-assisted analysis of valyala/fasthttp@c96f600972 (2026-08-31).
Data as JSON: /api/errors/06022721dca270c3.
Report an issue: GitHub.