valyala/fasthttp · error · ErrBrokenChunk
invalid character %q after chunk size
Error message
invalid character %q after chunk size
What it means
After the hexadecimal chunk size, fasthttp permits either an optional space/tab (optional-whitespace separator) or a chunk extension starting with ';'. If a ';' appears AFTER whitespace was already seen, the framing is invalid per fasthttp's request-smuggling-hardening rules, so it returns ErrBrokenChunk with this message.
Source
Thrown at http.go:3007
}
// Security: Don't allow newlines in chunk extensions.
// This can lead to request smuggling issues with some reverse proxies.
if c == '\n' {
return -1, ErrBrokenChunk{
error: errors.New("invalid character '\\n' after chunk size"),
}
}
if inExt {
continue
}
switch c {
case ' ', '\t':
afterSizeOWS = true
continue
case ';':
if afterSizeOWS {
return -1, ErrBrokenChunk{
error: fmt.Errorf("invalid character %q after chunk size", c),
}
}
inExt = true
continue
default:
return -1, ErrBrokenChunk{
error: fmt.Errorf("invalid character %q after chunk size", c),
}
}
}
err = readCrLf(r)
if err != nil {
return -1, err
}
return n, nil
}
func readCrLf(r *bufio.Reader) error {View on GitHub (pinned to c96f600972)
Solutions
- Fix the client/proxy to emit extensions directly after the size ("5;ext=1") with no space before ';'.
- Strip chunk extensions in the upstream producer; send a plain size line.
- If you own an intermediary, configure it to normalize chunked framing before forwarding.
- Drop the request as smuggling-suspect: handle ErrBrokenChunk and close the connection (fasthttp already does this).
Example fix
// before (wire format) 5 ;ext=1\r\nhello\r\n0\r\n\r\n // after 5;ext=1\r\nhello\r\n0\r\n\r\n
Defensive patterns
Strategy: try-catch
Validate before calling
// Server-side: if you control ingress, reject chunk extensions after OWS // with a pre-check proxy rule: // deny requests whose chunk-size lines match /(^|\r\n)[0-9a-fA-F]+[ \t]+;/
Type guard
func isChunkExtAfterOWS(err error) bool {
var bc fasthttp.ErrBrokenChunk
return errors.As(err, &bc) &&
strings.Contains(bc.error.Error(), "invalid character")
} Try / catch
var bc fasthttp.ErrBrokenChunk
if errors.As(err, &bc) {
// possible request-smuggling attempt: drop and close
ctx.ConnectionClose()
return
} Prevention
- Fix clients/proxies to emit chunk extensions as "size;ext", never "size ;ext".
- Keep fasthttp's strict framing; do not relax it — it blocks request smuggling.
- Log offending peers; this pattern often indicates scanning/smuggling probes.
- Normalize chunked framing at a single trusted edge proxy.
When it happens
Trigger: A peer sends a chunk-size line like "5 ;ext=1" — i.e. chunk extension after an OWS separator. Rejected here to prevent request smuggling through reverse proxies.
Common situations: Requests forwarded through non-conforming proxies/clients that emit "size ;ext" chunk lines; hand-rolled HTTP clients or fuzzers; request-smuggling probe traffic.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- unexpected char %q at the end of chunk size: expected %q
- cannot read '\r' char at the end of chunk size: %w
- empty hex number
- invalid character '\n' after chunk size
- cannot unread '\r' char at the end of chunk size: %w
AI-assisted analysis of valyala/fasthttp@c96f600972 (2026-08-31).
Data as JSON: /api/errors/97f8ea5b15d59341.
Report an issue: GitHub.