{"record":{"id":"39091165e8d0443d","repo":"valyala/fasthttp","slug":"fasthttp-requesturi-cannot-be-empty","errorCode":null,"errorMessage":"fasthttp: requesturi cannot be empty","messagePattern":"fasthttp: requesturi cannot be empty","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"header.go","lineNumber":477,"sourceCode":"// 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),\n// 2. routing (e.g., Host),","sourceCodeStart":459,"sourceCodeEnd":495,"githubUrl":"https://github.com/valyala/fasthttp/blob/c96f600972c6f4a7a30d664257b340ebe9d60124/header.go#L459-L495","documentation":"An HTTP request line must contain a request-target (URI/path) after the method. fasthttp returns ErrEmptyRequestURI when the request URI is missing or empty while building or parsing a request, because a request without a target cannot be routed or sent.","triggerScenarios":"Calling Request.Write/Client.Do with a Request whose RequestURI was never set (req.SetRequestURI not called), resetting a reused Request and forgetting to re-set the URI, or parsing a request line like 'GET HTTP/1.1' with no target.","commonSituations":"Proxy/middleware code that mutates req.SetRequestURIBytes conditionally so the URI is dropped on some paths; HostClient.Do with req URI set only via Host header; zero-value Request structs passed to Do.","solutions":["Always call req.SetRequestURI(\"http://host/path\") (or SetRequestURIBytes) before Do/Write.","Check conditional mutation logic — ensure the branch that clears or skips SetRequestURI cannot run.","For reused pooled Request objects, re-set URI after Reset() since Reset wipes it.","On server side, respond 400 to clients that omit the request target."],"exampleFix":"// before\nreq := fasthttp.AcquireRequest()\nreq.Header.SetMethod(fasthttp.MethodGet)\nclient.Do(req, resp) // empty requestURI\n// after\nreq := fasthttp.AcquireRequest()\nreq.Header.SetMethod(fasthttp.MethodGet)\nreq.SetRequestURI(\"https://example.com/api\")\nclient.Do(req, resp)","handlingStrategy":"validation","validationCode":"if len(req.Header.RequestURI()) == 0 {\n    return errors.New(\"requestURI is empty; call SetRequestURI before Do\")\n}\n// optionally validate scheme+host too:\n// u := fasthttp.AcquireURI(); defer fasthttp.ReleaseURI(u)\n// req.URI().CopyTo(u)","typeGuard":"func hasRequestURI(req *fasthttp.Request) bool {\n    return len(req.Header.RequestURI()) > 0\n}","tryCatchPattern":"if err := client.Do(req, resp); err == fasthttp.ErrEmptyRequestURI {\n    return fmt.Errorf(\"request sent without URI: %w\", err)\n}","preventionTips":["Make SetRequestURI the first call after acquiring a Request — order matters in builders.","Re-set URI after Reset() on pooled/reused Requests.","Review proxy/middleware code for branches that skip URI assignment.","Add a debug assertion (hasRequestURI) in tests covering every request-construction path."],"tags":["http","fasthttp","request-validation"],"backgroundTag":"invalid-http-request","analyzedSha":"c96f600972c6f4a7a30d664257b340ebe9d60124","analyzedAt":"2026-08-31T22:48:28.265Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}