valyala/fasthttp · error
unsupported transfer-encoding: %q
Error message
unsupported transfer-encoding: %q
What it means
fasthttp rejects a Transfer-Encoding header whose value is not 'chunked' (case-insensitive). RFC 7230 only allows 'chunked' as the final transfer coding, so any other value makes the message framing unparseable and fasthttp closes the connection (connectionClose=true). When secureErrorLogMessage is enabled the sentinel ErrUnsupportedTransferEncoding is returned instead of the value-embedding message.
Source
Thrown at header.go:3114
case 't':
if caseInsensitiveCompare(s.key, strTransferEncoding) {
if h.noHTTP11 {
continue
}
if transferEncodingSeen {
h.connectionClose = true
if h.secureErrorLogMessage {
return 0, ErrUnsupportedTransferEncoding
}
return 0, errors.New("too many transfer-encoding headers")
}
transferEncodingSeen = true
if !caseInsensitiveCompare(s.value, strChunked) {
h.connectionClose = true
if h.secureErrorLogMessage {
return 0, ErrUnsupportedTransferEncoding
}
return 0, fmt.Errorf("unsupported transfer-encoding: %q", s.value)
}
h.contentLength = -1
h.h = setArgBytes(h.h, strTransferEncoding, strChunked, argsHasValue)
continue
}
if caseInsensitiveCompare(s.key, strTrailer) {
err := h.SetTrailerBytes(s.value)
if err != nil {
h.connectionClose = true
return 0, err
}
continue
}
}
h.h = appendArgBytes(h.h, s.key, s.value, argsHasValue)
}
if s.err != nil {View on GitHub (pinned to c96f600972)
Solutions
- Remove the Transfer-Encoding header and send the body with Content-Length instead, or use exactly 'Transfer-Encoding: chunked'.
- If the intent is compression, set Content-Encoding: gzip on the body, not Transfer-Encoding.
- Fix the upstream client/proxy that emits the non-chunked transfer coding.
- If you control the server and only need to avoid echoing header values in logs, set Server.SecureErrorLogMessage to get the sanitized error.
Example fix
// before (client hand-rolled request)
req.Header.Set("Transfer-Encoding", "gzip")
// after
req.Header.Set("Content-Encoding", "gzip")
req.Header.Set("Transfer-Encoding", "chunked") Defensive patterns
Strategy: validation
Validate before calling
func validTransferEncoding(te string) bool {
return strings.EqualFold(strings.TrimSpace(te), "chunked") || te == ""
}
// check before sending: if !validTransferEncoding(te) { fix or drop header } Try / catch
var errUnsupportedTE = errors.New("unsupported transfer-encoding")
if err := server.ServeConn(...); err != nil && strings.Contains(err.Error(), "unsupported transfer-encoding") {
// close connection / return 400 to client
} Prevention
- Only ever send Transfer-Encoding: chunked
- Use Content-Encoding for compression, never Transfer-Encoding
- Test clients against a strict HTTP linter (h2spec, net/http roundtrip)
When it happens
Trigger: Parsing a request/response whose Transfer-Encoding header is set to something other than 'chunked' or 'identity'-style values — e.g. 'Transfer-Encoding: gzip', 'compress', 'deflate', or a malformed multi-value like 'chunked, gzip' in the wrong order.
Common situations: Proxies or clients behind middleware that compresses bodies and rewrites headers; hand-rolled HTTP clients setting Transfer-Encoding instead of Content-Encoding; misconfigured load balancers adding transfer codings.
Related errors
- fasthttp: unsupported transfer-encoding
- fasthttp: contain forbidden trailer
- fasthttp: error when reading response headers
- fasthttp: error when reading response trailer
- fasthttp: cannot find whitespace in the first line of respon
AI-assisted analysis of valyala/fasthttp@c96f600972 (2026-08-31).
Data as JSON: /api/errors/9291d6b8f05d2bed.
Report an issue: GitHub.