valyala/fasthttp · error
empty hex number
Error message
empty hex number
What it means
errEmptyHexNum is returned by readHexInt when the chunked transfer-encoding size line contains no hexadecimal digits. readHexInt parses chunk sizes while reading chunked request/response bodies, so this error indicates a malformed chunked stream rather than bad user code. It is a declared sentinel, comparable with errors.Is.
Source
Thrown at bytesconv.go:368
}
// ParseUfloat parses unsigned float from buf.
func ParseUfloat(buf []byte) (float64, error) {
// The implementation of parsing a float string is not easy.
// We believe that the conservative approach is to call strconv.ParseFloat.
// https://github.com/valyala/fasthttp/pull/1865
res, err := strconv.ParseFloat(b2s(buf), 64)
if res < 0 {
return -1, errors.New("negative input is invalid")
}
if err != nil {
return -1, err
}
return res, err
}
var (
errEmptyHexNum = errors.New("empty hex number")
errTooLargeHexNum = errors.New("too large hex number")
)
func readHexInt(r *bufio.Reader) (int, error) {
var k, i, n int
for {
c, err := r.ReadByte()
if err != nil {
if err == io.EOF && i > 0 {
return n, nil
}
return -1, err
}
k = int(hex2intTable[c])
if k == 16 {
if i == 0 {
return -1, errEmptyHexNum
}View on GitHub (pinned to c96f600972)
Solutions
- Verify the sending client/proxy implements chunked transfer encoding correctly; test with curl or a reference client.
- Handle the error where you read the body and return 400 Bad Request, since the request framing is corrupt.
- If streams come from an untrusted network, cap read sizes/timeouts (fasthttp ReadTimeout, max body size) so malformed streams fail fast.
- Ensure intermediaries are not mangling the body (some proxies re-chunk or strip chunk extensions incorrectly).
Defensive patterns
Strategy: try-catch
Validate before calling
// Cannot pre-validate chunk framing; instead bound the read:
server := &fasthttp.Server{
ReadTimeout: 10 * time.Second,
MaxRequestBodySize: 8 << 20,
} Try / catch
if err := bodyHandler(ctx); err != nil {
if err.Error() == "empty hex number" {
ctx.Error("malformed chunked encoding", fasthttp.StatusBadRequest)
return
}
return err
} Prevention
- Enforce ReadTimeout and MaxRequestBodySize on the fasthttp.Server
- Test clients against a reference HTTP implementation (curl, net/http)
- Watch for proxies that re-chunk or corrupt transfer framing
- Treat this error as a client/protocol fault, not an application bug
When it happens
Trigger: Reading a chunked body where a chunk-size line is empty or starts with a non-hex character, e.g. a client sending '\r\n' where a hex length was expected, or a truncated chunked stream.
Common situations: Misbehaving HTTP clients or proxies emitting invalid chunked encoding; connections cut mid-stream so the size line never arrives; custom/proxied payloads with framing mistakes.
Related errors
- cannot read '\r' char at the end of chunk size: %w
- invalid character %q after chunk size
- unexpected char %q at the end of chunk size: expected %q
- too large hex number
- cannot find crlf at the end of chunk
AI-assisted analysis of valyala/fasthttp@c96f600972 (2026-08-31).
Data as JSON: /api/errors/fdb1ab11da390b8f.
Report an issue: GitHub.