{"record":{"id":"97f8ea5b15d59341","repo":"valyala/fasthttp","slug":"invalid-character-q-after-chunk-size","errorCode":null,"errorMessage":"invalid character %q after chunk size","messagePattern":"invalid character %q after chunk size","errorType":"exception","errorClass":"ErrBrokenChunk","httpStatus":null,"severity":"error","filePath":"http.go","lineNumber":3007,"sourceCode":"\t\t}\n\t\t// Security: Don't allow newlines in chunk extensions.\n\t\t// This can lead to request smuggling issues with some reverse proxies.\n\t\tif c == '\\n' {\n\t\t\treturn -1, ErrBrokenChunk{\n\t\t\t\terror: errors.New(\"invalid character '\\\\n' after chunk size\"),\n\t\t\t}\n\t\t}\n\t\tif inExt {\n\t\t\tcontinue\n\t\t}\n\t\tswitch c {\n\t\tcase ' ', '\\t':\n\t\t\tafterSizeOWS = true\n\t\t\tcontinue\n\t\tcase ';':\n\t\t\tif afterSizeOWS {\n\t\t\t\treturn -1, ErrBrokenChunk{\n\t\t\t\t\terror: fmt.Errorf(\"invalid character %q after chunk size\", c),\n\t\t\t\t}\n\t\t\t}\n\t\t\tinExt = true\n\t\t\tcontinue\n\t\tdefault:\n\t\t\treturn -1, ErrBrokenChunk{\n\t\t\t\terror: fmt.Errorf(\"invalid character %q after chunk size\", c),\n\t\t\t}\n\t\t}\n\t}\n\terr = readCrLf(r)\n\tif err != nil {\n\t\treturn -1, err\n\t}\n\treturn n, nil\n}\n\nfunc readCrLf(r *bufio.Reader) error {","sourceCodeStart":2989,"sourceCodeEnd":3025,"githubUrl":"https://github.com/valyala/fasthttp/blob/c96f600972c6f4a7a30d664257b340ebe9d60124/http.go#L2989-L3025","documentation":"After the hexadecimal chunk size, fasthttp permits either an optional space/tab (optional-whitespace separator) or a chunk extension starting with ';'. If a ';' appears AFTER whitespace was already seen, the framing is invalid per fasthttp's request-smuggling-hardening rules, so it returns ErrBrokenChunk with this message.","triggerScenarios":"A peer sends a chunk-size line like \"5 ;ext=1\" — i.e. chunk extension after an OWS separator. Rejected here to prevent request smuggling through reverse proxies.","commonSituations":"Requests forwarded through non-conforming proxies/clients that emit \"size ;ext\" chunk lines; hand-rolled HTTP clients or fuzzers; request-smuggling probe traffic.","solutions":["Fix the client/proxy to emit extensions directly after the size (\"5;ext=1\") with no space before ';'.","Strip chunk extensions in the upstream producer; send a plain size line.","If you own an intermediary, configure it to normalize chunked framing before forwarding.","Drop the request as smuggling-suspect: handle ErrBrokenChunk and close the connection (fasthttp already does this)."],"exampleFix":"// before (wire format)\n5 ;ext=1\\r\\nhello\\r\\n0\\r\\n\\r\\n\n// after\n5;ext=1\\r\\nhello\\r\\n0\\r\\n\\r\\n","handlingStrategy":"try-catch","validationCode":"// Server-side: if you control ingress, reject chunk extensions after OWS\n// with a pre-check proxy rule:\n// deny requests whose chunk-size lines match /(^|\\r\\n)[0-9a-fA-F]+[ \\t]+;/","typeGuard":"func isChunkExtAfterOWS(err error) bool {\n    var bc fasthttp.ErrBrokenChunk\n    return errors.As(err, &bc) &&\n        strings.Contains(bc.error.Error(), \"invalid character\")\n}","tryCatchPattern":"var bc fasthttp.ErrBrokenChunk\nif errors.As(err, &bc) {\n    // possible request-smuggling attempt: drop and close\n    ctx.ConnectionClose()\n    return\n}","preventionTips":["Fix clients/proxies to emit chunk extensions as \"size;ext\", never \"size ;ext\".","Keep fasthttp's strict framing; do not relax it — it blocks request smuggling.","Log offending peers; this pattern often indicates scanning/smuggling probes.","Normalize chunked framing at a single trusted edge proxy."],"tags":["fasthttp","chunked-encoding","request-smuggling","http-protocol"],"backgroundTag":"broken-chunked-body","analyzedSha":"c96f600972c6f4a7a30d664257b340ebe9d60124","analyzedAt":"2026-08-31T22:48:28.265Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}