cloudflare/cloudflared · error
Error setting content-length: %w
Error message
Error setting content-length: %w
What it means
After building the origin request, buildHTTPRequest calls setContentLength to ensure the request is not silently sent with chunked transfer encoding. If setContentLength fails (e.g. the request body does not support Len()/known length), the error is wrapped as "Error setting content-length". Without this, Go's http.Client would buffer or chunk bodies unexpectedly, breaking some origin servers.
Source
Thrown at connection/quic_connection.go:373
return nil, err
}
req.Host = host
for _, metadata := range connectRequest.Metadata {
if strings.Contains(metadata.Key, HTTPHeaderKey) {
// metadata.Key is off the format httpHeaderKey:<HTTPHeader>
httpHeaderKey := strings.Split(metadata.Key, ":")
if len(httpHeaderKey) != 2 {
return nil, fmt.Errorf("header Key: %s malformed", metadata.Key)
}
req.Header.Add(httpHeaderKey[1], metadata.Val)
}
}
// Go's http.Client automatically sends chunked request body if this value is not set on the
// *http.Request struct regardless of header:
// https://go.googlesource.com/go/+/go1.8rc2/src/net/http/transfer.go#154.
if err := setContentLength(req); err != nil {
return nil, fmt.Errorf("Error setting content-length: %w", err)
}
// Go's client defaults to chunked encoding after a 200ms delay if the following cases are true:
// * the request body blocks
// * the content length is not set (or set to -1)
// * the method doesn't usually have a body (GET, HEAD, DELETE, ...)
// * there is no transfer-encoding=chunked already set.
// So, if transfer cannot be chunked and content length is 0, we dont set a request body.
if !isWebsocket && !isTransferEncodingChunked(req) && req.ContentLength == 0 {
req.Body = http.NoBody
}
stripWebsocketUpgradeHeader(req)
// Check for tracing on request
tracedReq := tracing.NewTracedHTTPRequest(req, connIndex, log)
return tracedReq, err
}
View on GitHub (pinned to 2253eeeb25)
Solutions
- Provide a request body with a known length (bytes.Buffer, bytes.Reader, strings.Reader) so ContentLength can be inferred
- Explicitly set ContentLength on the upstream request if the client knows the size
- Inspect setContentLength's inner error (via %w unwrap) to see why length detection failed
- If the body is intentionally unbounded, ensure the origin server accepts chunked encoding and consider bypassing length enforcement
Example fix
// before body := io.Reader(pipeReader) // unknown length // after bodyBytes, _ := io.ReadAll(pipeReader) req.Body = io.NopCloser(bytes.NewReader(bodyBytes)) // length now measurable
Defensive patterns
Strategy: try-catch
Validate before calling
// ensure the body length is known before proxying
switch b := body.(type) {
case *bytes.Buffer, *bytes.Reader, *strings.Reader:
// length is auto-detected; ok
default:
log.Println("warning: body has unknown length; content-length may fail")
} Try / catch
req, err := buildHTTPRequest(ctx, connectReq, reader, ...)
if err != nil {
var clErr *fmt.wrapError
if errors.As(err, &clErr) && strings.Contains(err.Error(), "Error setting content-length") {
// fall back to chunked encoding or reject the request with 411 Length Required
}
return err
} Prevention
- Use bytes.Reader/strings.Reader/bytes.Buffer for request bodies so ContentLength is inferred
- Set req.ContentLength explicitly when the size is known
- Avoid passing io.Readers without length info for proxied bodies
When it happens
Trigger: The proxied request's body cannot provide a deterministic content length — e.g. a body whose ContentLength is -1 and whose reader cannot be measured, so setContentLength cannot determine or set req.ContentLength.
Common situations: Streaming request bodies of unknown size from the origin client; bodies wrapped in readers that don't implement length introspection; very large uploads that edge delivers as unbounded streams.
Understand the failure class
Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.
Related errors
- header Key: %s malformed
- unsupported error type: %s
- can't create %s request
- Error Parsing page %d
- failed to request quick Tunnel
AI-assisted analysis of cloudflare/cloudflared@2253eeeb25 (2026-09-06).
Data as JSON: /api/errors/b45da317c092f512.
Report an issue: GitHub.