valyala/fasthttp · error

error when reading %s headers: %w: buffer size=%d, contents:

Error message

error when reading %s headers: %w: buffer size=%d, contents: %s

What it means

This error wraps any failure encountered while reading HTTP headers off the wire, including the buffer size and (unless secure error logging is enabled) a snippet of the raw bytes received. fasthttp throws it when header parsing fails so the developer can see exactly what malformed data arrived and how much of it fit in the buffer.

Source

Thrown at header.go:2303

	// Buggy servers may leave trailing CRLFs after http body.
	// Treat this case as EOF.
	if isOnlyCRLF(b) {
		return io.EOF
	}

	if err != bufio.ErrBufferFull {
		return headerErrorMsg(typ, err, b, secureErrorLogMessage)
	}
	return &ErrSmallBuffer{
		error: headerErrorMsg(typ, ErrSmallReadBuffer, b, secureErrorLogMessage),
	}
}

func headerErrorMsg(typ string, err error, b []byte, secureErrorLogMessage bool) error {
	if secureErrorLogMessage {
		return fmt.Errorf("error when reading %s headers: %w: buffer size=%d", typ, err, len(b))
	}
	return fmt.Errorf("error when reading %s headers: %w: buffer size=%d, contents: %s", typ, err, len(b), bufferSnippet(b))
}

// Read reads request header from r.
//
// io.EOF is returned if r is closed before reading the first header byte.
func (h *RequestHeader) Read(r *bufio.Reader) error {
	return h.readLoop(r, true)
}

// readLoop reads request header from r optionally loops until it has enough data.
//
// io.EOF is returned if r is closed before reading the first header byte.
func (h *RequestHeader) readLoop(r *bufio.Reader, waitForMore bool) error {
	n := 1
	for {
		err := h.tryRead(r, n)
		if err == nil {
			return nil

View on GitHub (pinned to c96f600972)

Solutions

  1. Inspect the 'contents' snippet in the error to identify the malformed bytes the peer sent
  2. Increase Server.ReadBufferSize (or Client.ReadBufferSize) if headers are legitimately large
  3. Enable Server.SecureErrorLogMessage in production to avoid echoing raw request bytes to logs
  4. Reject or rate-limit the offending client; the data is malformed and cannot be parsed

Example fix

// before
srv := &fasthttp.Server{Handler: h}
// after
srv := &fasthttp.Server{Handler: h, ReadBufferSize: 16384, SecureErrorLogMessage: true}
Defensive patterns

Strategy: try-catch

Type guard

func isHeaderReadError(err error) bool {
    return err != nil && strings.Contains(err.Error(), "error when reading")
}

Try / catch

err := fasthttp.Do(req, resp)
if err != nil && strings.Contains(err.Error(), "error when reading") {
    log.Warn("malformed headers from peer", "err", err)
    return errPeerMalformedResponse
}

Prevention

When it happens

Trigger: RequestHeader.Read or ResponseHeader.Read fails during parsing (via headerError) when the header block is malformed, too large, or the underlying bufio.Reader errors — and secureErrorLogMessage is false.

Common situations: Clients sending non-HTTP garbage to a fasthttp server; headers exceeding the configured ReadBufferSize; proxies forwarding truncated or corrupted header blocks; fuzzing or port scanners hitting the port.

Related errors


AI-assisted analysis of valyala/fasthttp@c96f600972 (2026-08-31). Data as JSON: /api/errors/d709517f93fb1671. Report an issue: GitHub.