{"record":{"id":"4314fd160f832a0a","repo":"projectdiscovery/nuclei","slug":"failed-to-read-body-s","errorCode":null,"errorMessage":"failed to read body: %s","messagePattern":"failed to read body: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/input/types/http.go","lineNumber":297,"sourceCode":"\t\t// read it off the URL: retryablehttp derives the wire Host from there,\n\t\t// and keeping it in the header map would expose it to header fuzzing as\n\t\t// if it were an ordinary header.\n\t\tif strings.EqualFold(key, \"Host\") {\n\t\t\t// an absolute request target takes precedence over the Host header\n\t\t\tif rr.URL.Host == \"\" {\n\t\t\t\trr.URL.Host = value\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\trr.Request.Headers.Set(key, value)\n\t}\n\n\t// parse body\n\trr.Request.Body = \"\"\n\tvar buff bytes.Buffer\n\t_, err = buff.ReadFrom(protoReader.R)\n\tif err != nil && err != io.EOF {\n\t\treturn nil, fmt.Errorf(\"failed to read body: %s\", err)\n\t}\n\tif buff.Len() > 0 {\n\t\t// yaml may include trailing newlines\n\t\t// remove them if present\n\t\tbin := buff.Bytes()\n\t\tif len(bin) > 0 && bin[len(bin)-1] == '\\n' {\n\t\t\tbin = bin[:len(bin)-1]\n\t\t}\n\t\tif len(bin) > 0 && (bin[len(bin)-1] == '\\r' || bin[len(bin)-1] == '\\n') {\n\t\t\tbin = bin[:len(bin)-1]\n\t\t}\n\t\trr.Request.Body = conversion.String(bin)\n\t}\n\n\t// set raw request\n\trr.Request.Raw = raw\n\treturn rr, nil\n}","sourceCodeStart":279,"sourceCodeEnd":315,"githubUrl":"https://github.com/projectdiscovery/nuclei/blob/265b3a3dec374741614e342f813c10f8b38d2bb7/pkg/input/types/http.go#L279-L315","documentation":"After headers, ParseRawRequest slurps the remaining body via buff.ReadFrom(protoReader.R) and any error other than io.EOF is wrapped here. The reader is a strings.Reader, so in the shipped code path this is practically unreachable; seeing it means a reader-level failure or a modified build.","triggerScenarios":"Calling ParseRawRequest in a fork/patched build where the reader can fail mid-stream; essentially never with the standard strings.Reader-based implementation.","commonSituations":"Custom builds wrapping the reader; out-of-memory conditions on enormous bodies; vendored forks that changed the input source.","solutions":["Confirm you are on an unmodified nuclei release (this path is a no-op guard)","If it reproduces on a fork, inspect what protoReader.R is backed by in that build","Shrink the raw request body to rule out resource exhaustion"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"Wrap ParseRawRequest and treat any body-read failure as fatal for that entry; with stock builds this is a should-never-happen guard, so if it fires, capture the raw input and report a bug.","preventionTips":["Run official releases; this path guards a strings.Reader that cannot fail","If you fork the parser, ensure your reader returns io.EOF at end of body"],"tags":["input","raw-http","rare"],"backgroundTag":null,"analyzedSha":"265b3a3dec374741614e342f813c10f8b38d2bb7","analyzedAt":"2026-08-15T20:05:51.855Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}