valyala/fasthttp · error

cannot parse ip string %q: %w

Error message

cannot parse ip string %q: %w

What it means

ParseIPv4 parses a dotted-quad IPv4 string into a 4-byte array. When parsing an octet via parseIPv4Octet fails with an error other than the 'part too large' sentinel (e.g. empty part, non-digit characters, too many digits), the error is wrapped with the original input string via %w so callers can errors.Is/As the underlying cause.

Source

Thrown at bytesconv.go:97

	}
	if len(dst) < net.IPv4len || len(dst) > net.IPv4len {
		dst = make([]byte, net.IPv4len)
	}
	copy(dst, net.IPv4zero)
	dst = dst.To4() // dst is always non-nil here

	b := ipStr
	for i := range 3 {
		n := bytes.IndexByte(b, '.')
		if uint(n) >= uint(len(b)) {
			return dst, fmt.Errorf("cannot find dot in ip string %q", ipStr)
		}
		octet, parsed, err := parseIPv4Octet(b[:n])
		if err != nil {
			if errors.Is(err, errIPv4PartTooLarge) {
				return dst, fmt.Errorf("cannot parse ip string %q: ip part cannot exceed 255: parsed %d", ipStr, parsed)
			}
			return dst, fmt.Errorf("cannot parse ip string %q: %w", ipStr, err)
		}
		dst[i] = octet
		b = b[n+1:]
	}
	octet, parsed, err := parseIPv4Octet(b)
	if err != nil {
		if errors.Is(err, errIPv4PartTooLarge) {
			return dst, fmt.Errorf("cannot parse ip string %q: ip part cannot exceed 255: parsed %d", ipStr, parsed)
		}
		return dst, fmt.Errorf("cannot parse ip string %q: %w", ipStr, err)
	}
	dst[3] = octet

	return dst, nil
}

// AppendHTTPDate appends HTTP-compliant (RFC1123) representation of date
// to dst and returns the extended dst.

View on GitHub (pinned to c96f600972)

Solutions

  1. Print the wrapped inner error (%w) to see the exact per-octet failure
  2. Validate the string matches ^\d{1,3}(\.\d{1,3}){3}$ before parsing
  3. Trim whitespace and BOM characters from the input before parsing
  4. Use net.ParseIP as a pre-check if you only need validation, not the fast byte form

Example fix

// before
var ip [4]byte
_, err := fasthttp.ParseIPv4(ip[:], []byte(strings.TrimSpace(cfg.Host))) // err: cannot parse ip string "1..2.3": ...
// after
host := strings.TrimSpace(cfg.Host)
if net.ParseIP(host) == nil {
    return fmt.Errorf("invalid ipv4 in config: %q", host)
}
_, err := fasthttp.ParseIPv4(ip[:], []byte(host))
Defensive patterns

Strategy: validation

Validate before calling

var ipv4Re = regexp.MustCompile(`^(\d{1,3})(\.\d{1,3}){3}$`)
if !ipv4Re.MatchString(ipStr) { return fmt.Errorf("not an ipv4 literal: %q", ipStr) }

Type guard

func isIPv4Literal(s string) bool {
    parts := strings.Split(s, ".")
    if len(parts) != 4 { return false }
    for _, p := range parts {
        if len(p) == 0 || len(p) > 3 { return false }
        n, err := strconv.Atoi(p)
        if err != nil || n > 255 { return false }
    }
    return true
}

Try / catch

dst := [4]byte{}
if _, err := fasthttp.ParseIPv4(dst[:], []byte(ipStr)); err != nil {
    if errors.Is(err, errIPv4PartTooLarge) { /* octet > 255 */ }
    return fmt.Errorf("parse %q: %w", ipStr, err)
}

Prevention

When it happens

Trigger: Calling fasthttp.ParseIPv4 (or code that uses it, e.g. AcquireURI/host parsing) with a string containing an invalid octet: empty components like "1..2.3", non-numeric characters like "1.2.3.a", or an octet with more than 3 digits.

Common situations: Hardcoded IPs with typos, IPs read from config files or environment variables with stray characters or double dots, values coming from user input or DNS text records that were not validated.

Related errors


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