valyala/fasthttp · error · ErrSmallBuffer
error when reading request headers: %w (n=%d, reader buffere
Error message
error when reading request headers: %w (n=%d, reader buffered=%d)
What it means
fasthttp wraps ErrSmallReadBuffer in an ErrSmallBuffer when reading request headers fills the bufio buffer without reaching the header terminator (\r\n\r\n). The error reports how many bytes were read and how many the reader had buffered, pinpointing that the configured buffer is too small for the incoming header block.
Source
Thrown at header.go:2346
}
}
func (h *RequestHeader) tryRead(r *bufio.Reader, n int) error {
h.resetSkipNormalize()
b, err := r.Peek(n)
if len(b) == 0 {
if err == io.EOF {
return err
}
if err == nil {
panic("bufio.Reader.Peek() returned nil, nil")
}
// This is for go 1.6 bug. See https://github.com/golang/go/issues/14121 .
if err == bufio.ErrBufferFull {
return &ErrSmallBuffer{
error: fmt.Errorf("error when reading request headers: %w (n=%d, reader buffered=%d)", ErrSmallReadBuffer, n, r.Buffered()),
}
}
// n == 1 on the first read for the request.
if n == 1 {
// We didn't read a single byte.
return ErrNothingRead{error: err}
}
return fmt.Errorf("error when reading request headers: %w", err)
}
b = mustPeekBuffered(r)
headersLen, errParse := h.parse(b)
if errParse != nil {
return headerError("request", err, errParse, b, h.secureErrorLogMessage)
}
if errValidate := h.validate(); errValidate != nil {
return headerError("request", err, errValidate, b, h.secureErrorLogMessage)View on GitHub (pinned to c96f600972)
Solutions
- Increase Server.ReadBufferSize so it exceeds the largest expected request header block
- Reduce header size on the client side (trim cookies, compress tokens, shorten tracing headers)
- If you control the proxy, strip unnecessary forwarded headers before they reach fasthttp
Example fix
// before
srv := &fasthttp.Server{Handler: h} // ReadBufferSize=4096
// after
srv := &fasthttp.Server{Handler: h, ReadBufferSize: 32768} Defensive patterns
Strategy: validation
Validate before calling
// ensure server buffer can hold worst-case headers
const maxHeaderBlock = 32 * 1024
srv := &fasthttp.Server{ReadBufferSize: maxHeaderBlock}
// client-side: keep request headers under the server's buffer
if len(cookieHeader) > 8*1024 {
return errors.New("cookie header too large")
} Type guard
func isSmallBufferErr(err error) bool {
var e *fasthttp.ErrSmallBuffer
return errors.As(err, &e)
} Try / catch
if err := h.Read(br); err != nil {
var sbe *fasthttp.ErrSmallBuffer
if errors.As(err, &sbe) {
return respondStatusBadRequest("headers too large")
}
return err
} Prevention
- Raise ReadBufferSize above the largest expected header block
- Keep cookies and auth tokens compact
- Strip redundant forwarded headers at the proxy
- Test with header-heavy clients during load testing
When it happens
Trigger: Server.ReadBufferSize (default 4096) is smaller than the total size of an incoming request's headers, so bufio.Reader.Peek returns bufio.ErrBufferFull inside RequestHeader.Read.
Common situations: Clients sending many/large cookies, long authorization JWTs, or custom tracing headers; servers left at default ReadBufferSize behind proxies that append headers (X-Forwarded-*, CDN headers).
Related errors
- fasthttp: small read buffer. increase readbuffersize
- fasthttp: contain forbidden trailer
- fasthttp: error when reading response headers
- fasthttp: error when reading response trailer
- fasthttp: cannot find whitespace in the first line of respon
AI-assisted analysis of valyala/fasthttp@c96f600972 (2026-08-31).
Data as JSON: /api/errors/a8a86b58bcb6d6f6.
Report an issue: GitHub.