{"record":{"id":"9d3835891b9381d9","repo":"valyala/fasthttp","slug":"non-zero-body-for-non-post-request-body-q","errorCode":null,"errorMessage":"non-zero body for non-post request: body=%q","messagePattern":"non-zero body for non-post request: body=%q","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"http.go","lineNumber":1867,"sourceCode":"\n\thasBody := false\n\tif len(body) == 0 {\n\t\tbody = req.postArgs.QueryString()\n\t}\n\tif len(body) != 0 || !req.Header.ignoreBody() {\n\t\thasBody = true\n\t\treq.Header.SetContentLength(len(body))\n\t}\n\tif err = req.Header.Write(w); err != nil {\n\t\treturn err\n\t}\n\tif hasBody {\n\t\t_, err = w.Write(body)\n\t} else if len(body) > 0 {\n\t\tif req.secureErrorLogMessage {\n\t\t\treturn errors.New(\"non-zero body for non-post request\")\n\t\t}\n\t\treturn fmt.Errorf(\"non-zero body for non-post request: body=%q\", body)\n\t}\n\treturn err\n}\n\n// WriteGzip writes response with gzipped body to w.\n//\n// The method gzips response body and sets 'Content-Encoding: gzip'\n// header before writing response to w.\n//\n// WriteGzip doesn't flush response to w for performance reasons.\nfunc (resp *Response) WriteGzip(w *bufio.Writer) error {\n\treturn resp.WriteGzipLevel(w, CompressDefaultCompression)\n}\n\n// WriteGzipLevel writes response with gzipped body to w.\n//\n// Level is the desired compression level:\n//","sourceCodeStart":1849,"sourceCodeEnd":1885,"githubUrl":"https://github.com/valyala/fasthttp/blob/c96f600972c6f4a7a30d664257b340ebe9d60124/http.go#L1849-L1885","documentation":"fasthttp refuses to write a request that has a non-empty body but is not a method that normally carries one (i.e. not POST and not flagged as having a body, such as via SetBytesBody on allowed methods or Request.SetHost style overrides). With secureErrorLogMessage the body is omitted from the message; otherwise the body content is quoted.","triggerScenarios":"Setting a body (SetBody/SetBodyString/SetFormFileContent without proper method) then issuing GET/HEAD/DELETE etc.; doRequest path builds the request with hasBody false but len(body) > 0.","commonSituations":"Copy-pasting POST code and changing only the method to GET while keeping the body; switching a client helper to HEAD for health checks while still setting a payload; middleware that clears the method but not the body.","solutions":["Set req.Header.SetMethod(fasthttp.MethodPost) (or PUT) when a body is intended.","Clear the body with req.ResetBody() when the method must remain GET/HEAD.","Check helper functions that set both method and body; only use the body-setting ones for POST/PUT.","If the server expects a body on GET, send POST instead or use a client that permits it explicitly."],"exampleFix":"// before\nreq.SetBodyString(payload)\nreq.Header.SetMethod(fasthttp.MethodGet)\n// after\nreq.Header.SetMethod(fasthttp.MethodPost)\nreq.SetBodyString(payload)","handlingStrategy":"validation","validationCode":"if req.Header.Method() != fasthttp.MethodPost && req.Header.Method() != fasthttp.MethodPut && len(req.Body()) > 0 {\n    return errors.New(\"body set on non-post request\")\n}","typeGuard":"func bodyAllowed(method []byte) bool {\n    switch string(method) {\n    case \"POST\", \"PUT\", \"PATCH\":\n        return true\n    }\n    return false\n}","tryCatchPattern":"if err := client.Do(req, resp); err != nil {\n    if strings.Contains(err.Error(), \"non-zero body for non-post request\") {\n        req.ResetBody()\n        req.Header.SetMethod(fasthttp.MethodPost)\n        return client.Do(req, resp)\n    }\n    return err\n}","preventionTips":["Always set the method explicitly when a body is present","Clear the body (ResetBody) when downgrading to GET/HEAD","Centralize request construction in helpers that pair method+body"],"tags":["http-method","request-body","validation"],"backgroundTag":"get-request-with-body","analyzedSha":"c96f600972c6f4a7a30d664257b340ebe9d60124","analyzedAt":"2026-08-31T22:48:28.265Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}