crowdsecurity/crowdsec · error
inconsistent size for range first(%d) and last(%d) ip
Error message
inconsistent size for range first(%d) and last(%d) ip
What it means
Range2Ints requires the first and last addresses of the range to have the same size class (4 for IPv4, 16 for IPv6). If IP2Ints returns different sizes for the network base and the broadcast address, this error is thrown. It signals a net.IPNet whose IP and Mask encode inconsistent families, so the range cannot be represented as a uniform integer span.
Source
Thrown at pkg/types/ip.go:75
return sz, start, end, start, end, nil
}
/*size (16|4), nw_start, suffix_start, nw_end, suffix_end, error*/
func Range2Ints(network net.IPNet) (int, int64, int64, int64, int64, error) {
szStart, nwStart, sfxStart, err := IP2Ints(network.IP)
if err != nil {
return -1, 0, 0, 0, 0, fmt.Errorf("converting first ip in range: %w", err)
}
lastAddr := LastAddress(network)
szEnd, nwEnd, sfxEnd, err := IP2Ints(lastAddr)
if err != nil {
return -1, 0, 0, 0, 0, fmt.Errorf("transforming last address of range: %w", err)
}
if szEnd != szStart {
return -1, 0, 0, 0, 0, fmt.Errorf("inconsistent size for range first(%d) and last(%d) ip", szStart, szEnd)
}
return szStart, nwStart, sfxStart, nwEnd, sfxEnd, nil
}
func uint2int(u uint64) int64 {
var ret int64
if u == math.MaxInt64 {
ret = 0
} else if u == math.MaxUint64 {
ret = math.MaxInt64
} else if u > math.MaxInt64 {
u -= math.MaxInt64
ret = int64(u)
} else {
ret = int64(u)
ret -= math.MaxInt64
}View on GitHub (pinned to 909b515798)
Solutions
- Keep both endpoints in the same family: call network.IP.To4() and use a 4-byte mask for IPv4, To16()/CIDRMask(n,128) for IPv6
- Parse CIDRs with net.ParseCIDR rather than constructing net.IPNet manually
- Log the two sizes from the message to identify which field is the wrong family
- Reject such IPNet values at the configuration-parsing boundary before numeric conversion
Example fix
// before
ipnet := net.IPNet{IP: net.ParseIP("192.168.1.0").To4(), Mask: net.CIDRMask(24, 128)}
_, _, _, _, _, err := types.Range2Ints(ipnet) // inconsistent size 4 vs 16
// after
ipnet := net.IPNet{IP: net.ParseIP("192.168.1.0").To4(), Mask: net.CIDRMask(24, 32)} Defensive patterns
Strategy: validation
Validate before calling
func sameFamilyEndpoints(n net.IPNet) bool {
last := types.LastAddress(n)
return (n.IP.To4() != nil) == (last.To4() != nil)
} Type guard
func uniformFamily(n net.IPNet) bool { return n.IP.To4() != nil && types.LastAddress(n).To4() != nil || n.IP.To4() == nil } Prevention
- Normalize both endpoints with the same To4()/To16() call before converting
- Construct IPNet values with matching family for IP and Mask
- Reject mixed-family CIDRs during input parsing
When it happens
Trigger: Range2Ints (or Addr2Ints with a CIDR) with a net.IPNet whose base IP normalizes to 4 bytes while the ORed host-mask address normalizes to 16 bytes (or vice versa) — i.e. mixed IPv4/IPv6 fields in one net.IPNet.
Common situations: Hand-built net.IPNet where IP is a 4-byte representation but the mask indexing produced a 16-byte result; code paths that convert only one endpoint with To4(); corrupted IPNet values from external data.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- converting first ip in range: %w
- transforming last address of range: %w
- crowdsec.enable not a string
- labels not a map
- missing allowed_ranges value for api.server.auto_register
AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06).
Data as JSON: /api/errors/7e614c12a2c09c87.
Report an issue: GitHub.