{"record":{"id":"02bf6093edc1e956","repo":"grpc/grpc-go","slug":"failed-to-convert-q-to-uint","errorCode":null,"errorMessage":"failed to convert %q to uint","messagePattern":"failed to convert %q to uint","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"internal/binarylog/env_config.go","lineNumber":169,"sourceCode":"\tservice = match[1]\n\tmethod = match[2]\n\tsuffix = match[3]\n\treturn\n}\n\n// Turn \"{h:123;m:345}\" into 123, 345.\n//\n// Return maxUInt if length is unspecified.\nfunc parseHeaderMessageLengthConfig(c string) (hdrLenStr, msgLenStr uint64, err error) {\n\tif c == \"\" {\n\t\treturn maxUInt, maxUInt, nil\n\t}\n\t// Header config only.\n\tif match := headerConfigRegexp.FindStringSubmatch(c); match != nil {\n\t\tif s := match[1]; s != \"\" {\n\t\t\thdrLenStr, err = strconv.ParseUint(s, 10, 64)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, 0, fmt.Errorf(\"failed to convert %q to uint\", s)\n\t\t\t}\n\t\t\treturn hdrLenStr, 0, nil\n\t\t}\n\t\treturn maxUInt, 0, nil\n\t}\n\n\t// Message config only.\n\tif match := messageConfigRegexp.FindStringSubmatch(c); match != nil {\n\t\tif s := match[1]; s != \"\" {\n\t\t\tmsgLenStr, err = strconv.ParseUint(s, 10, 64)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, 0, fmt.Errorf(\"failed to convert %q to uint\", s)\n\t\t\t}\n\t\t\treturn 0, msgLenStr, nil\n\t\t}\n\t\treturn 0, maxUInt, nil\n\t}\n","sourceCodeStart":151,"sourceCodeEnd":187,"githubUrl":"https://github.com/grpc/grpc-go/blob/0c51461d27177d997e14c642fe18c11668fc09a3/internal/binarylog/env_config.go#L151-L187","documentation":"Raised by parseHeaderMessageLengthConfig in the header-only branch `{h:N}`. The regex already matched `N` as digits (`\\d+`), so strconv.ParseUint only fails when N exceeds the uint64 maximum (18446744073709551615) or is otherwise unparseable at this stage. Wrapped as 'failed to convert %q to uint'.","triggerScenarios":"A config like `Foo/Bar{h:99999999999999999999999}` where the header byte limit overflows uint64. Effectively any header length that does not fit in 64 bits.","commonSituations":"Pasting a very large number intending 'unlimited'; misreading the doc and supplying a value with too many digits; generated configs that concatenate magnitudes.","solutions":["Replace the oversized value with a realistic byte limit (e.g. `256`, `1024`).","To mean 'no limit on headers', omit the number entirely: `Foo/Bar{h}`.","Validate that the number is within [0, 18446744073709551615] before constructing the string."],"exampleFix":"// before\nconfig := \"Foo/Bar{h:99999999999999999999999}\"\n// after\nconfig := \"Foo/Bar{h}\"","handlingStrategy":"validation","validationCode":"const maxU64 = uint64(18446744073709551615) // math.MaxUint64\nfunc validLengthField(s string) bool {\n    if s == \"\" { return true } // omit => unlimited\n    n, err := strconv.ParseUint(s, 10, 64)\n    return err == nil && n <= maxU64\n}","typeGuard":null,"tryCatchPattern":"Parse each {h:N} field yourself with strconv.ParseUint(_,10,64) before assembling the filter; on error replace with an empty value or a sane cap.","preventionTips":["Use an empty header number to mean 'unlimited' instead of a huge number.","Bound user-supplied byte limits to a realistic maximum (e.g. 1<<20).","Unit-test the filter builder with edge-case magnitudes."],"tags":["grpc","binary-log","config","parsing","overflow"],"backgroundTag":null,"analyzedSha":"0c51461d27177d997e14c642fe18c11668fc09a3","analyzedAt":"2026-08-11T14:49:15.055Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}