cloudflare/cloudflared · error
Error writing response header
Error message
Error writing response header
What it means
After a successful origin response, proxyHTTPRequest writes the status code and origin headers back to the edge via w.WriteRespHeaders. If that write fails, it is wrapped as 'Error writing response header'. This indicates the downstream connection to Cloudflare's edge (or the client) broke while relaying the response headers, not an origin problem.
Source
Thrown at proxy/proxy.go:243
}
return errors.Wrap(err, "Unable to reach the origin service. The service may be down or it may not be responding to traffic from cloudflared")
}
tracing.EndWithStatusCode(ttfbSpan, resp.StatusCode)
defer func() { _ = resp.Body.Close() }()
headers := make(http.Header, len(resp.Header))
// copy headers
for k, v := range resp.Header {
headers[k] = v
}
// Add spans to response header (if available)
tr.AddSpans(headers)
err = w.WriteRespHeaders(resp.StatusCode, headers)
if err != nil {
return errors.Wrap(err, "Error writing response header")
}
if resp.StatusCode == http.StatusSwitchingProtocols {
rwc, ok := resp.Body.(io.ReadWriteCloser)
if !ok {
return errors.New("internal error: unsupported connection type")
}
defer func() { _ = rwc.Close() }()
eyeballStream := &bidirectionalStream{
writer: w,
reader: tr.Body,
}
stream.Pipe(eyeballStream, rwc, logger)
return nil
}
View on GitHub (pinned to 2253eeeb25)
Solutions
- Check whether the end client actually cancelled/aborted the request; this is usually benign client disconnect noise.
- Verify network stability between cloudflared and Cloudflare edge (look for repeated reconnects in the log).
- Inspect origin response headers for invalid values (control characters, oversized headers) that fail transport encoding.
- Retry the request; a one-off error during an edge reconnect is transient.
Defensive patterns
Strategy: retry
Validate before calling
// validate origin headers before relay: reject control chars
for k, vs := range resp.Header {
for _, v := range vs {
if strings.ContainsAny(v, "\r\n\x00") {
return fmt.Errorf("invalid header value for %s", k)
}
}
} Try / catch
if err := w.WriteRespHeaders(resp.StatusCode, headers); err != nil {
// log at debug: usually client/edge disconnect, not actionable
log.Debug().Err(err).Msg("client disconnected before headers written")
return err
} Prevention
- Treat this as transient: most occurrences are client aborts or edge reconnects.
- Sanitize origin response headers if the origin is third-party or misconfigured.
- Monitor tunnel-to-edge connection stability metrics.
- Avoid oversized response headers from the origin (e.g. giant Set-Cookie chains).
When it happens
Trigger: w.WriteRespHeaders(resp.StatusCode, headers) returns an error — typically because the underlying stream/connection to the edge is closed, reset, or the headers cannot be encoded on the transport.
Common situations: Client disconnected or page reload before response headers were sent; edge connection dropped due to network interruption; invalid/duplicate hop-by-hop headers from the origin causing encoding failure on the tunnel transport.
Related errors
- Unable to reach the origin service. The service may be down
- unable to wait for both streams while proxying
- quick tunnel provisioning failed
- funnel not found
- internal error: unsupported connection type
AI-assisted analysis of cloudflare/cloudflared@2253eeeb25 (2026-09-06).
Data as JSON: /api/errors/b5de096bc43412a9.
Report an issue: GitHub.