{"record":{"id":"f08f072c2f52973e","repo":"valyala/fasthttp","slug":"fasthttp-extra-whitespace-in-request-line","errorCode":null,"errorMessage":"fasthttp: extra whitespace in request line","messagePattern":"fasthttp: extra whitespace in request line","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"header.go","lineNumber":476,"sourceCode":"// 3. request modifiers (e.g., controls and conditionals in Section 5 of [RFC7231]),\n// 4. authentication (e.g., see [RFC7235] and [RFC6265]),\n// 5. response control data (e.g., see Section 7.1 of [RFC7231]),\n// 6. determining how to process the payload (e.g., Content-Encoding, Content-Type, Content-Range, and Trailer)\n//\n// Return ErrBadTrailer if contain any forbidden trailers.\nfunc (h *header) AddTrailer(trailer string) error {\n\treturn h.AddTrailerBytes(s2b(trailer))\n}\n\nvar (\n\tErrBadTrailer                    = errors.New(\"fasthttp: contain forbidden trailer\")\n\tErrReadingResponseHeaders        = errors.New(\"fasthttp: error when reading response headers\")\n\tErrReadingResponseTrailer        = errors.New(\"fasthttp: error when reading response trailer\")\n\tErrResponseFirstLineMissingSpace = errors.New(\"fasthttp: cannot find whitespace in the first line of response\")\n\tErrUnexpectedStatusCodeChar      = errors.New(\"fasthttp: unexpected char at the end of status code\")\n\tErrMissingRequestMethod          = errors.New(\"fasthttp: cannot find http request method\")\n\tErrUnsupportedRequestMethod      = errors.New(\"fasthttp: unsupported http request method\")\n\tErrExtraWhitespaceInRequestLine  = errors.New(\"fasthttp: extra whitespace in request line\")\n\tErrEmptyRequestURI               = errors.New(\"fasthttp: requesturi cannot be empty\")\n\tErrDuplicateContentLength        = errors.New(\"fasthttp: duplicate content-length header\")\n\tErrUnsupportedTransferEncoding   = errors.New(\"fasthttp: unsupported transfer-encoding\")\n\tErrNonNumericChars               = errors.New(\"fasthttp: non-numeric chars found\")\n\tErrNeedMore                      = errors.New(\"fasthttp: need more data: cannot find trailing lf\")\n\tErrSmallReadBuffer               = errors.New(\"fasthttp: small read buffer. increase readbuffersize\")\n)\n\n// AddTrailerBytes add Trailer header value for chunked response\n// to indicate which headers will be sent after the body.\n//\n// Use Set to set the trailer header later.\n//\n// Trailers are only supported with chunked transfer.\n// Trailers allow the sender to include additional headers at the end of chunked messages.\n//\n// The following trailers are forbidden:\n// 1. necessary for message framing (e.g., Transfer-Encoding and Content-Length),","sourceCodeStart":458,"sourceCodeEnd":494,"githubUrl":"https://github.com/valyala/fasthttp/blob/c96f600972c6f4a7a30d664257b340ebe9d60124/header.go#L458-L494","documentation":"When parsing a request line, fasthttp splits it into method, requestURI, and protocol by whitespace. If it encounters more whitespace than expected between the tokens (e.g. multiple spaces), ErrExtraWhitespaceInRequestLine is returned. Strict parsing here prevents request smuggling via odd spacing.","triggerScenarios":"Reading (Request.Read / server-side request parse) a request line like 'GET  /path HTTP/1.1' (double space) or with stray tabs between method/URI/protocol; crafted requests from clients attempting parser confusion.","commonSituations":"A nonconformant HTTP client or hand-written client emitting padded request lines; load balancers or security scanners sending malformed probes; fuzz tests against your fasthttp server.","solutions":["Fix the upstream client to emit single-space-separated request lines per RFC 7230.","Identify the offending client via access logs or by capturing raw bytes (fasthttputil.NewInetListener + manual read).","If a proxy/load balancer rewrites request lines, disable that rewriting.","On your server, treat this as client error and return 400; no server-side code change is needed since fasthttp rejects it safely."],"exampleFix":"// before\nraw := \"GET  /index HTTP/1.1\\r\\nHost: x\\r\\n\\r\\n\" // double space\n// after\nraw := \"GET /index HTTP/1.1\\r\\nHost: x\\r\\n\\r\\n\"","handlingStrategy":"type-guard","validationCode":"// For raw request construction, assert single spaces:\n// regexp.MustCompile(`^[A-Z]+ [^ ]+ HTTP/1\\.[01]$`).MatchString(requestLine)","typeGuard":"func isRequestLineWellFormed(line []byte) bool {\n    parts := bytes.Fields(line)\n    return len(parts) == 3 && len(bytes.Split(line, []byte(\" \"))) == 3\n}","tryCatchPattern":"if err := req.Read(r); err == fasthttp.ErrExtraWhitespaceInRequestLine {\n    // log offending client, respond 400 / drop connection\n    return fmt.Errorf(\"malformed request line: %w\", err)\n}","preventionTips":["Never build request lines by string concatenation with variable spacing — use fasthttp APIs.","Fuzz-test your server; this error usually indicates a probing or buggy client, not your bug.","Audit intermediaries (LBs, security tools) that rewrite request lines.","Keep rejecting it: allowing extra whitespace enables request smuggling."],"tags":["http","fasthttp","request-parsing","security"],"backgroundTag":"invalid-http-request","analyzedSha":"c96f600972c6f4a7a30d664257b340ebe9d60124","analyzedAt":"2026-08-31T22:48:28.265Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}