valyala/fasthttp · error
unexpected trailing char found: expecting 0-9
Error message
unexpected trailing char found: expecting 0-9
What it means
errUnexpectedTrailingChar is returned by ParseUint and parseIPv4Octet when digits are followed by a non-digit character. ParseUint consumes all input and requires it to be entirely numeric, so values like "12x" or "1.5" fail with this error. It signals malformed numeric input with trailing garbage.
Source
Thrown at bytesconv.go:278
// ParseUint parses uint from buf.
//
// A value too large for an int is an error rather than a wrapped result, so
// ParseUint accepts exactly the unsigned decimal strings whose value fits in an
// int on the current platform.
func ParseUint(buf []byte) (int, error) {
v, n, err := parseUintBuf(buf)
if n != len(buf) {
return -1, errUnexpectedTrailingChar
}
return v, err
}
var (
errEmptyInt = errors.New("empty integer")
errIPv4PartTooLarge = errors.New("ip part cannot exceed 255")
errUnexpectedFirstChar = errors.New("unexpected first char found: expecting 0-9")
errUnexpectedTrailingChar = errors.New("unexpected trailing char found: expecting 0-9")
errTooLongInt = errors.New("too long int")
)
const (
// maxIntDiv10 is the largest accumulator that can still take another digit.
// Anything above it overflows an int when multiplied by 10.
maxIntDiv10 = math.MaxInt / 10
// maxSafeIntDigits is how many leading decimal digits can never overflow an
// int, whatever the word size: 10**18-1 fits a 64-bit int and 10**9-1 fits a
// 32-bit one. Go defines strconv.IntSize as 32 or 64 and nothing else.
// TestMaxSafeIntDigits checks both halves of that claim on the build's own
// int size.
maxSafeIntDigits = 9 * (strconv.IntSize / 32)
)
func parseUintBuf(b []byte) (int, int, error) {
if len(b) == 0 {View on GitHub (pinned to c96f600972)
Solutions
- Validate the whole string is digits (e.g. bytes.IndexFunc(buf, nonDigit) < 0) before parsing.
- Use strconv.ParseFloat / ParseInt directly if the input legitimately contains decimals or signs — fasthttp's ParseUint is deliberately strict.
- Split the input on the expected delimiter first (e.g. cut the port off 'host:port') and parse only the numeric part.
- Return 400 for client-supplied values since this is malformed user input, not a server fault.
Example fix
// before
n, err := fasthttp.ParseUint([]byte("1.5"))
// after
f, err := strconv.ParseFloat("1.5", 64) // floats need a float parser
// or, for strict uint:
if !isAllDigits(buf) { return 0, errors.New("expected unsigned integer") }
n, err := fasthttp.ParseUint(buf) Defensive patterns
Strategy: validation
Validate before calling
func parseUintStrict(b []byte) (int, error) {
if !digitsOnly(b) {
return 0, fmt.Errorf("trailing characters in %q", b)
}
return fasthttp.ParseUint(b)
}
func digitsOnly(b []byte) bool {
return len(b) > 0 && bytes.IndexFunc(b, func(r rune) bool { return r < '0' || r > '9' }) < 0
} Type guard
func isAllDigits(b []byte) bool {
return len(b) > 0 && bytes.IndexFunc(b, func(r rune) bool { return r < '0' || r > '9' }) < 0
} Try / catch
n, err := fasthttp.ParseUint(b)
if err != nil && err.Error() == "unexpected trailing char found: expecting 0-9" {
return 0, fmt.Errorf("%q must be a plain integer", b)
} Prevention
- Split compound values ('host:port', '8080/tcp') before parsing
- Use float parsers for decimal input
- Strip units/suffixes from config values before parsing
- Return 400 for malformed client-supplied numbers
When it happens
Trigger: ParseUint([]byte("8080/tcp")) (EXPOSE-style values), ParseUint([]byte("1.5")) (float passed to int parser), ParseIPv4 with a component like "1a.2.3.4"; also Args.GetUint where the value has trailing characters.
Common situations: Float values sent to integer parsers; values with units ('100ms', '5kb'); header values with inline comments or ports; form fields where clients append stray characters.
Related errors
- empty integer
- unexpected first char found: expecting 0-9
- too long int
- fasthttp: no args value for the given key
- empty ip address string
AI-assisted analysis of valyala/fasthttp@c96f600972 (2026-08-31).
Data as JSON: /api/errors/809a93e8b2b63d2b.
Report an issue: GitHub.