grafana/k6 · error

mixed IP range format: {s}

Error message

mixed IP range format: {s}

What it means

Returned by ipBlockFromRange (lib/types/ipblock.go:49-51) when both endpoints of an IP range parse as IPs but one is IPv4 and the other IPv6 ((ip0.To4() == nil) != (ip1.To4() == nil) XOR check). A single ipBlock tracks one address family (block.ipv6 is set from ip0 alone in ipBlockFromTwoIPs), so mixed-family ranges cannot be represented and are rejected.

Source

Thrown at lib/types/ipblock.go:50

		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)
	block.ipv6 = ip0.To4() == nil
	if block.ipv6 {
		block.firstIP.SetBytes(ip0.To16())

View on GitHub (pinned to 93accf6570)

Solutions

  1. Keep both endpoints in the same family, e.g. '::1-::ff' or '10.0.0.1-10.0.0.10'
  2. If both families are needed, define two separate blocks, one per family

Example fix

// before
block, err := getIPBlock("10.0.0.1-::ffff")

// after
block, err := getIPBlock("10.0.0.1-10.0.0.10")
Defensive patterns

Strategy: validation

Validate before calling

// Go: ensure both endpoints are the same address family
func sameFamily(s string) bool {
    a, b, _ := strings.Cut(s, "-")
    ipa, ipb := net.ParseIP(a), net.ParseIP(b)
    return ipa != nil && ipb != nil && ((ipa.To4() == nil) == (ipb.To4() == nil))
}

Prevention

When it happens

Trigger: Calling getIPBlock with something like '::1-192.168.0.10' or '10.0.0.1-ffff::2' — both sides syntactically valid IPs, but of different families.

Common situations: Config generation joining a v4 start and v6 end from different variables; dual-stack configs where a template's start/end fields were filled from different address families.

Related errors


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