grafana/k6 · error

wrong IP range format: {s}

Error message

wrong IP range format: {s}

What it means

Returned by ipBlockFromRange (lib/types/ipblock.go:46-48) when parsing an IP range 'start-end' where at least one side fails net.ParseIP. getIPBlock splits the string on the first '-' (strings.Cut, line 42) and both halves must be valid literal IPv4 or IPv6 addresses; this constructor is reached from the range branch (and from the single-IP default branch which synthesizes 'ip-ip').

Source

Thrown at lib/types/ipblock.go:47

func getIPBlock(s string) (*ipBlock, error) {
	switch {
	case strings.Contains(s, "-"):
		return ipBlockFromRange(s)
	case strings.Contains(s, "/"):
		return ipBlockFromCIDR(s)
	default:
		if net.ParseIP(s) == nil {
			return nil, fmt.Errorf("%s is not a valid IP, IP range or CIDR", s)
		}
		return ipBlockFromRange(s + "-" + s)
	}
}

func ipBlockFromRange(s string) (*ipBlock, error) {
	ip0Str, ip1Str, _ := strings.Cut(s, "-")
	ip0, ip1 := net.ParseIP(ip0Str), net.ParseIP(ip1Str)
	if ip0 == nil || ip1 == nil {
		return nil, errors.New("wrong IP range format: " + s)
	}
	if (ip0.To4() == nil) != (ip1.To4() == nil) { // XOR
		return nil, errors.New("mixed IP range format: " + s)
	}
	block := ipBlockFromTwoIPs(ip0, ip1)

	if block.count.Sign() <= 0 {
		return nil, errors.New("negative IP range: " + s)
	}
	return block, nil
}

func ipBlockFromTwoIPs(ip0, ip1 net.IP) *ipBlock {
	// This code doesn't do any checks on the validity of the arguments, that should be
	// done before and/or after it is called
	var block ipBlock
	block.firstIP = new(big.Int)
	block.count = new(big.Int)

View on GitHub (pinned to 93accf6570)

Solutions

  1. Provide both endpoints as full literal IPs: '192.168.0.1-192.168.0.100'
  2. For a single IP, pass just '192.168.0.1' (the default branch wraps it into a one-IP range)
  3. For a network, prefer CIDR notation like '192.168.0.0/24', which is handled before the range branch

Example fix

// before
block, err := getIPBlock("192.168.0.300-192.168.0.400")

// after
block, err := getIPBlock("192.168.0.1-192.168.0.100")
Defensive patterns

Strategy: validation

Validate before calling

// Go: validate an IP range string before using it as a types IP block
func validateIPRange(s string) error {
    a, b, ok := strings.Cut(s, "-")
    if !ok {
        return fmt.Errorf("%q is not a range; expected 'startIP-endIP'", s)
    }
    if net.ParseIP(a) == nil || net.ParseIP(b) == nil {
        return fmt.Errorf("%q: both endpoints must be literal IPs", s)
    }
    return nil
}

Prevention

When it happens

Trigger: Calling getIPBlock (via the types.IPBlock parsing surface, ipblock.go:124) with values like '192.168.0.256-192.168.0.300' (out-of-range octets), '192.168.0-192.168.0.5' (incomplete address), 'foo-bar', or a CIDR string that fell through to the range branch.

Common situations: Typos in IP allowlists/blocklists in configs; specifying a hostnames or domain where an IP range is required (names are never resolved here); truncated values from templating.

Related errors


AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15). Data as JSON: /api/errors/f63ccde9404ae755. Report an issue: GitHub.