valyala/fasthttp · error

negative input is invalid

Error message

negative input is invalid

What it means

ParseUfloat parses an unsigned float from a byte slice via strconv.ParseFloat, then rejects results below zero with an ad-hoc errors.New("negative input is invalid"). It is raised inside ParseUfloat itself (not a declared sentinel), so callers must match on the message or pre-validate. Note the check runs before err is examined, so a negative result triggers this even on parse warnings.

Source

Thrown at bytesconv.go:359

			return 0, parsed, errUnexpectedTrailingChar
		}
		parsed = parsed*10 + int(k)
		if octet > 25 || (octet == 25 && k > 5) {
			return 0, parsed, errIPv4PartTooLarge
		}
		octet = octet*10 + k
	}
	return octet, parsed, nil
}

// 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 {

View on GitHub (pinned to c96f600972)

Solutions

  1. Validate the first byte is not '-' before calling ParseUfloat and give the user a clear message.
  2. Catch the error and compare err.Error() == "negative input is invalid" to branch on this specific case, since no sentinel is exported.
  3. If negative values are legitimate, use strconv.ParseFloat(string(buf), 64) directly instead of ParseUfloat.
  4. Return 400 for user input, or clamp negatives to 0 if the domain allows it.

Example fix

// before
v, err := fasthttp.ParseUfloat(b) // "negative input is invalid"
// after
if len(b) > 0 && b[0] == '-' {
    return 0, errors.New("value must be non-negative")
}
v, err := fasthttp.ParseUfloat(b)
Defensive patterns

Strategy: validation

Validate before calling

func parseUfloatNonNeg(b []byte) (float64, error) {
    if len(b) > 0 && b[0] == '-' {
        return 0, errors.New("value must be non-negative")
    }
    return fasthttp.ParseUfloat(b)
}

Type guard

func isNonNegativeNumber(b []byte) bool {
    return len(b) > 0 && b[0] != '-'
}

Try / catch

v, err := fasthttp.ParseUfloat(b)
if err != nil {
    if err.Error() == "negative input is invalid" {
        return 0, errors.New("negative values are not allowed here")
    }
    return err
}

Prevention

When it happens

Trigger: ParseUfloat([]byte("-1.5")) or args.GetUfloat on a value like ?price=-3.2 — any input whose parsed float is negative.

Common situations: Client sending negative values for quantities that must be non-negative (prices, percentages, weights); sign typos ('-0.5' instead of '0.5'); signed sensors/offsets fed to an unsigned parser.

Related errors


AI-assisted analysis of valyala/fasthttp@c96f600972 (2026-08-31). Data as JSON: /api/errors/5167a462a85ca23b. Report an issue: GitHub.