valyala/fasthttp · error
invalid WriteHeader code %v
Error message
invalid WriteHeader code %v
What it means
fasthttpadaptor's writer adapts net/http handlers to fasthttp. WriteHeader mirrors net/http's constraint that status codes must be 100-999 and panics otherwise, since fasthttp cannot encode such a code on the wire.
Source
Thrown at fasthttpadaptor/adaptor.go:251
}
}
func releaseWriter(w *writer) {
_ = w.Close()
if w.bufPool != nil {
bufferPool.Put(w.bufPool)
w.bufPool = nil
}
}
func (w *writer) Header() http.Header {
return w.h
}
func (w *writer) WriteHeader(code int) {
// Allow the same codes as net/http.
if code < 100 || code > 999 {
panic(fmt.Sprintf("invalid WriteHeader code %v", code))
}
w.statusCode.CompareAndSwap(0, int64(code))
}
func (w *writer) Write(p []byte) (int, error) {
select {
case <-w.streamReady:
return w.pw.Write(p)
default:
}
w.mu.Lock()
select {
case <-w.streamReady:
w.mu.Unlock()
return w.pw.Write(p)
default:
}View on GitHub (pinned to c96f600972)
Solutions
- Only pass valid HTTP status codes 100-999 to WriteHeader
- Default to http.StatusOK (200) when no explicit status is needed — omitting WriteHeader entirely also yields 200
- Clamp/validate the status value before calling WriteHeader
Example fix
// before
w.WriteHeader(status) // status may be 0
// after
if status < 100 || status > 999 {
status = http.StatusOK
}
w.WriteHeader(status) Defensive patterns
Strategy: try-catch
Validate before calling
func safeWriteHeader(w http.ResponseWriter, code int) {
if code >= 100 && code <= 999 {
w.WriteHeader(code)
}
} Type guard
func isValidStatusCode(code int) bool {
return code >= 100 && code <= 999
} Try / catch
func(w http.ResponseWriter, r *http.Request) {
defer func() {
if rec := recover(); rec != nil {
if s, ok := rec.(string); ok && strings.HasPrefix(s, "invalid WriteHeader code") {
http.Error(w, "internal error", http.StatusInternalServerError)
return
}
panic(rec)
}
}()
nextHandler(w, r)
} Prevention
- Never call WriteHeader with zero-valued or sentinel status variables
- Initialize status constants to http.StatusOK, not 0
- Centralize status writing behind a helper that validates the range
When it happens
Trigger: A net/http handler (served via adaptor) calls w.WriteHeader with code < 100 (e.g. 0, 42, 99) or > 999; the panic propagates up through ServeHTTP.
Common situations: Custom status constants initialized to zero and never set (WriteHeader(0)); experiments with out-of-range codes; copied handler code using sentinel values like -1.
Related errors
- invalid response status code %q: response %q
- fasthttp: no args value for the given key
- fasthttp: pipelined requests' queue has been overflowed. inc
- pipeline connection has been stopped
- fasthttp: no cookies found
AI-assisted analysis of valyala/fasthttp@c96f600972 (2026-08-31).
Data as JSON: /api/errors/265a2ea3588200ea.
Report an issue: GitHub.