{"record":{"id":"fdb1ab11da390b8f","repo":"valyala/fasthttp","slug":"empty-hex-number","errorCode":null,"errorMessage":"empty hex number","messagePattern":"empty hex number","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"bytesconv.go","lineNumber":368,"sourceCode":"}\n\n// ParseUfloat parses unsigned float from buf.\nfunc ParseUfloat(buf []byte) (float64, error) {\n\t// The implementation of parsing a float string is not easy.\n\t// We believe that the conservative approach is to call strconv.ParseFloat.\n\t// https://github.com/valyala/fasthttp/pull/1865\n\tres, err := strconv.ParseFloat(b2s(buf), 64)\n\tif res < 0 {\n\t\treturn -1, errors.New(\"negative input is invalid\")\n\t}\n\tif err != nil {\n\t\treturn -1, err\n\t}\n\treturn res, err\n}\n\nvar (\n\terrEmptyHexNum    = errors.New(\"empty hex number\")\n\terrTooLargeHexNum = errors.New(\"too large hex number\")\n)\n\nfunc readHexInt(r *bufio.Reader) (int, error) {\n\tvar k, i, n int\n\tfor {\n\t\tc, err := r.ReadByte()\n\t\tif err != nil {\n\t\t\tif err == io.EOF && i > 0 {\n\t\t\t\treturn n, nil\n\t\t\t}\n\t\t\treturn -1, err\n\t\t}\n\t\tk = int(hex2intTable[c])\n\t\tif k == 16 {\n\t\t\tif i == 0 {\n\t\t\t\treturn -1, errEmptyHexNum\n\t\t\t}","sourceCodeStart":350,"sourceCodeEnd":386,"githubUrl":"https://github.com/valyala/fasthttp/blob/c96f600972c6f4a7a30d664257b340ebe9d60124/bytesconv.go#L350-L386","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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)."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Cannot pre-validate chunk framing; instead bound the read:\nserver := &fasthttp.Server{\n    ReadTimeout: 10 * time.Second,\n    MaxRequestBodySize: 8 << 20,\n}","typeGuard":null,"tryCatchPattern":"if err := bodyHandler(ctx); err != nil {\n    if err.Error() == \"empty hex number\" {\n        ctx.Error(\"malformed chunked encoding\", fasthttp.StatusBadRequest)\n        return\n    }\n    return err\n}","preventionTips":["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"],"tags":["chunked-encoding","http-protocol","malformed-input"],"backgroundTag":"malformed-chunked-encoding","analyzedSha":"c96f600972c6f4a7a30d664257b340ebe9d60124","analyzedAt":"2026-08-31T22:48:28.265Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}