{"record":{"id":"ba682b16b157e3a8","repo":"valyala/fasthttp","slug":"fasthttp-non-numeric-chars-found","errorCode":null,"errorMessage":"fasthttp: non-numeric chars found","messagePattern":"fasthttp: non-numeric chars found","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"header.go","lineNumber":480,"sourceCode":"//\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),\n// 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]),","sourceCodeStart":462,"sourceCodeEnd":498,"githubUrl":"https://github.com/valyala/fasthttp/blob/c96f600972c6f4a7a30d664257b340ebe9d60124/header.go#L462-L498","documentation":"fasthttp parses numeric header values such as Content-Length with strict digit checks; ErrNonNumericChars is returned when a numeric header field contains characters other than digits (e.g. 'Content-Length: 12abc'). It prevents silently truncating or misinterpreting numbers used for body framing.","triggerScenarios":"Reading a Request/Response whose Content-Length (or other parsed numeric field) contains letters, spaces, '+', or signs — e.g. 'Content-Length: 100x'. Seen in tests like TestRequestReadLimitBodyContentLengthAndTransferEncoding where a malformed length is fed to req.Read.","commonSituations":"Buggy clients/proxies writing Content-Length with whitespace or garbage; corrupted responses from flaky upstreams; deliberately malformed traffic from security scanners.","solutions":["Fix the sender so Content-Length is a pure ASCII decimal string with no padding.","Use chunked transfer-encoding when the length is unknown instead of guessing a padded value.","Capture the offending message (reverse proxy logging) and repair or drop it at the edge.","For your own code, never format Content-Length manually — let fasthttp compute it via SetContentLength(len(body)) or leave it unset."],"exampleFix":"// before\ns := \"POST / HTTP/1.1\\r\\nHost: x\\r\\nContent-Length: 12ab\\r\\n\\r\\n\" // non-numeric\n// after\ns := \"POST / HTTP/1.1\\r\\nHost: x\\r\\nContent-Length: 12\\r\\n\\r\\n\"","handlingStrategy":"type-guard","validationCode":"if cl := req.Header.Peek(\"Content-Length\"); len(cl) > 0 {\n    if _, err := strconv.ParseUint(string(cl), 10, 63); err != nil {\n        return fmt.Errorf(\"invalid Content-Length %q\", cl)\n    }\n}","typeGuard":"func isNonNumericHeader(err error) bool {\n    return err == fasthttp.ErrNonNumericChars\n}","tryCatchPattern":"if err := req.Read(r); err == fasthttp.ErrNonNumericChars {\n    return fmt.Errorf(\"peer sent non-numeric Content-Length: %w\", err)\n}","preventionTips":["Let fasthttp compute Content-Length (SetContentLength(len(body))); never hand-format it.","Fix clients/proxies that pad numeric headers with spaces or append garbage.","Prefer chunked encoding when length is unknown.","Log and reject malformed numeric headers at the edge — they often come from scanners."],"tags":["http","fasthttp","header-parsing","validation"],"backgroundTag":"invalid-content-length","analyzedSha":"c96f600972c6f4a7a30d664257b340ebe9d60124","analyzedAt":"2026-08-31T22:48:28.265Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}