valyala/fasthttp · error

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

Error message

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

What it means

headerErrorMsg formats the final error for request/response header reads. In secure-error-log mode it hides the sniffed buffer contents and only reports the message plus buffer size, to avoid leaking request/response data into logs.

Source

Thrown at header.go:2301

	}

	// 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)

View on GitHub (pinned to c96f600972)

Solutions

  1. Increase ReadBufferSize (server or client) if ErrSmallReadBuffer is the cause
  2. Temporarily disable secure error logging in dev to see offending header contents
  3. Reduce the size of the headers being sent
  4. Keep secure logging on in production and rely on buffer size in the message to size buffers

Example fix

// before
s := &fasthttp.Server{ReadBufferSize: 4096}
// after
s := &fasthttp.Server{ReadBufferSize: 65536}
Defensive patterns

Strategy: type-guard

Validate before calling

// pick ReadBufferSize >= largest expected header block before deploying

Type guard

func isSmallReadBuffer(err error) bool { return errors.Is(err, fasthttp.ErrSmallReadBuffer) || errors.As(err, new(*fasthttp.ErrSmallBuffer)) }

Try / catch

if err := server.ServeConn(...); err != nil { if isSmallReadBuffer(err) { log.Printf("buffer too small: %v", err) } } // in dev call srv.SetSecureErrorLogger(false) to see contents

Prevention

When it happens

Trigger: Any header read error where RequestHeader/ResponseHeader.secureErrorLogMessage is true (set via SetSecureErrorLogger) — the wrapped error (e.g. ErrSmallReadBuffer) is reported with typ 'request'/'response' and the buffer length instead of its contents.

Common situations: Production servers with secure logging enabled hitting small-buffer header errors; developers confused why the error no longer shows header contents.

Related errors


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