valyala/fasthttp · error
fasthttp: non-numeric chars found
Error message
fasthttp: non-numeric chars found
What it means
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.
Source
Thrown at header.go:480
//
// Return ErrBadTrailer if contain any forbidden trailers.
func (h *header) AddTrailer(trailer string) error {
return h.AddTrailerBytes(s2b(trailer))
}
var (
ErrBadTrailer = errors.New("fasthttp: contain forbidden trailer")
ErrReadingResponseHeaders = errors.New("fasthttp: error when reading response headers")
ErrReadingResponseTrailer = errors.New("fasthttp: error when reading response trailer")
ErrResponseFirstLineMissingSpace = errors.New("fasthttp: cannot find whitespace in the first line of response")
ErrUnexpectedStatusCodeChar = errors.New("fasthttp: unexpected char at the end of status code")
ErrMissingRequestMethod = errors.New("fasthttp: cannot find http request method")
ErrUnsupportedRequestMethod = errors.New("fasthttp: unsupported http request method")
ErrExtraWhitespaceInRequestLine = errors.New("fasthttp: extra whitespace in request line")
ErrEmptyRequestURI = errors.New("fasthttp: requesturi cannot be empty")
ErrDuplicateContentLength = errors.New("fasthttp: duplicate content-length header")
ErrUnsupportedTransferEncoding = errors.New("fasthttp: unsupported transfer-encoding")
ErrNonNumericChars = errors.New("fasthttp: non-numeric chars found")
ErrNeedMore = errors.New("fasthttp: need more data: cannot find trailing lf")
ErrSmallReadBuffer = errors.New("fasthttp: small read buffer. increase readbuffersize")
)
// AddTrailerBytes add Trailer header value for chunked response
// to indicate which headers will be sent after the body.
//
// Use Set to set the trailer header later.
//
// Trailers are only supported with chunked transfer.
// Trailers allow the sender to include additional headers at the end of chunked messages.
//
// The following trailers are forbidden:
// 1. necessary for message framing (e.g., Transfer-Encoding and Content-Length),
// 2. routing (e.g., Host),
// 3. request modifiers (e.g., controls and conditionals in Section 5 of [RFC7231]),
// 4. authentication (e.g., see [RFC7235] and [RFC6265]),
// 5. response control data (e.g., see Section 7.1 of [RFC7231]),View on GitHub (pinned to c96f600972)
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.
Example fix
// before s := "POST / HTTP/1.1\r\nHost: x\r\nContent-Length: 12ab\r\n\r\n" // non-numeric // after s := "POST / HTTP/1.1\r\nHost: x\r\nContent-Length: 12\r\n\r\n"
Defensive patterns
Strategy: type-guard
Validate before calling
if cl := req.Header.Peek("Content-Length"); len(cl) > 0 {
if _, err := strconv.ParseUint(string(cl), 10, 63); err != nil {
return fmt.Errorf("invalid Content-Length %q", cl)
}
} Type guard
func isNonNumericHeader(err error) bool {
return err == fasthttp.ErrNonNumericChars
} Try / catch
if err := req.Read(r); err == fasthttp.ErrNonNumericChars {
return fmt.Errorf("peer sent non-numeric Content-Length: %w", err)
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: Buggy clients/proxies writing Content-Length with whitespace or garbage; corrupted responses from flaky upstreams; deliberately malformed traffic from security scanners.
Related errors
- fasthttp: duplicate content-length header
- fasthttp: unsupported transfer-encoding
- fasthttp: small read buffer. increase readbuffersize
- unsupported range units: %q: expecting %q
- missing byte range in %q
AI-assisted analysis of valyala/fasthttp@c96f600972 (2026-08-31).
Data as JSON: /api/errors/ba682b16b157e3a8.
Report an issue: GitHub.