{"record":{"id":"18866f78a4731dfa","repo":"valyala/fasthttp","slug":"cannot-gunzip-request-body-w","errorCode":null,"errorMessage":"cannot gunzip request body: %w","messagePattern":"cannot gunzip request body: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"http.go","lineNumber":1164,"sourceCode":"func (req *Request) MultipartFormWithLimit(maxBodySize int) (*multipart.Form, error) {\n\tif req.multipartForm != nil {\n\t\treturn req.multipartForm, nil\n\t}\n\n\treq.multipartFormBoundary = string(req.Header.MultipartFormBoundary())\n\tif req.multipartFormBoundary == \"\" {\n\t\treturn nil, ErrNoMultipartForm\n\t}\n\n\tvar err error\n\tce := req.Header.peek(strContentEncoding)\n\n\tif req.bodyStream != nil {\n\t\tbodyStream := req.bodyStream\n\t\tvar lr *io.LimitedReader\n\t\tif bytes.Equal(ce, strGzip) {\n\t\t\tif bodyStream, err = gzip.NewReader(bodyStream); err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"cannot gunzip request body: %w\", err)\n\t\t\t}\n\t\t} else if len(ce) > 0 {\n\t\t\treturn nil, fmt.Errorf(\"unsupported content-encoding: %q\", ce)\n\t\t}\n\t\tif maxBodySize > 0 {\n\t\t\tlr = &io.LimitedReader{\n\t\t\t\tR: bodyStream,\n\t\t\t\tN: int64(maxBodySize) + 1,\n\t\t\t}\n\t\t\tbodyStream = lr\n\t\t}\n\n\t\tmr := multipart.NewReader(bodyStream, req.multipartFormBoundary)\n\t\treq.multipartForm, err = mr.ReadForm(8 * 1024)\n\t\tif err != nil {\n\t\t\tif lr != nil && lr.N <= 0 {\n\t\t\t\treturn nil, fmt.Errorf(\"cannot read multipart/form-data body: %w\", ErrBodyTooLarge)\n\t\t\t}","sourceCodeStart":1146,"sourceCodeEnd":1182,"githubUrl":"https://github.com/valyala/fasthttp/blob/c96f600972c6f4a7a30d664257b340ebe9d60124/http.go#L1146-L1182","documentation":"When reading the request body (Request.Body/StreamBody path), fasthttp transparently decompresses a body whose Content-Encoding is gzip via gzip.NewReader. If the gzip stream is corrupt or truncated, the reader construction fails and the error is wrapped as 'cannot gunzip request body'. Any other non-empty Content-Encoding is rejected as unsupported.","triggerScenarios":"Client sends 'Content-Encoding: gzip' but the body is not valid gzip data (plain text, partially sent, or doubly-compressed), or uses an unsupported encoding like deflate/br.","commonSituations":"Clients gzipping bodies with broken streaming code; double compression through a proxy; test scripts sending fake gzip; clients using brotli/deflate expecting server support.","solutions":["Verify the client actually gzips the body (gzip.Writer with Close/Flush called before send).","Remove Content-Encoding: gzip if the body is plain, or switch to the encoding fasthttp supports.","If you need deflate/brotli, handle decompression manually: read the raw body stream yourself instead of relying on auto-gunzip.","Check for proxies that re-compress or truncate the body in transit."],"exampleFix":"// before (body not actually gzip)\nreq.Header.Set(\"Content-Encoding\", \"gzip\")\nreq.SetBodyString(\"hello\")\n// after\nvar buf bytes.Buffer\ngz := gzip.NewWriter(&buf)\ngz.Write([]byte(\"hello\"))\ngz.Close()\nreq.Header.Set(\"Content-Encoding\", \"gzip\")\nreq.SetBodyRaw(buf.Bytes())","handlingStrategy":"try-catch","validationCode":"func isRealGzip(body []byte) bool {\n    return len(body) > 2 && body[0] == 0x1f && body[1] == 0x8b\n} // only set Content-Encoding: gzip if this passes","typeGuard":null,"tryCatchPattern":"body, err := req.Body() // or StreamBody\nif err != nil {\n    var gze *gzip.HeaderError\n    if strings.Contains(err.Error(), \"cannot gunzip request body\") || errors.As(err, &gze) {\n        // read raw body instead: req.BodyRaw(), or respond 400\n    }\n}","preventionTips":["Always Close()/Flush() gzip.Writer before sending the body","Only set Content-Encoding when the body really is compressed","Avoid double compression through chained proxies","Prefer no Content-Encoding unless both ends agree on gzip"],"tags":["http","fasthttp","gzip","content-encoding"],"backgroundTag":"gzip-decompress-failed","analyzedSha":"c96f600972c6f4a7a30d664257b340ebe9d60124","analyzedAt":"2026-08-31T22:48:28.265Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}