crowdsecurity/crowdsec · error
converting first ip in range: %w
Error message
converting first ip in range: %w
What it means
Range2Ints converts a net.IPNet range into integer bounds. Before doing anything else it converts the network's first address (network.IP) via IP2Ints; if that fails, the failure is wrapped with this message. It indicates the network's base IP is nil or has an unusable byte length (not 4 or 16 bytes).
Source
Thrown at pkg/types/ip.go:64
ip := net.ParseIP(anyIP)
if ip == nil {
return -1, 0, 0, 0, 0, fmt.Errorf("invalid ip address '%s'", anyIP)
}
sz, start, end, err := IP2Ints(ip)
if err != nil {
return -1, 0, 0, 0, 0, fmt.Errorf("invalid ip address '%s': %w", anyIP, err)
}
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 int64View on GitHub (pinned to 909b515798)
Solutions
- Validate the net.IPNet before calling: ensure network.IP != nil and network.IP.To16() != nil
- Parse CIDR strings with net.ParseCIDR before calling Range2Ints so IP and Mask are consistent
- Inspect the wrapped error to see the unexpected IP length and fix the source that produced the IP
- Return/report the original input string so the user knows which value is malformed
Example fix
// before
net2 := net.IPNet{Mask: net.CIDRMask(24, 32)} // IP is nil
_, _, _, _, _, err := types.Range2Ints(net2)
// after
_, ipnet, err := net.ParseCIDR("192.168.1.0/24")
if err != nil { return err }
_, _, _, _, _, err := types.Range2Ints(*ipnet) Defensive patterns
Strategy: validation
Validate before calling
func validRange(n net.IPNet) bool { return n.IP != nil && n.IP.To16() != nil && n.Mask != nil } Type guard
func isParsableIP(ip net.IP) bool { return ip != nil && ip.To16() != nil } Prevention
- Always build net.IPNet via net.ParseCIDR, never struct literals
- Validate IPs at the config-parsing boundary
- Test both IPv4 and IPv6 inputs
When it happens
Trigger: Calling Range2Ints (directly or via Addr2Ints on a CIDR string) with a net.IPNet whose IP field is nil or a zero-length/invalid net.IP — e.g. a hand-constructed net.IPNet{Mask: ...} without IP, or an IP that fails both To4() and To16().
Common situations: Building net.IPNet structs manually from config or untrusted input where the IP was never parsed; parsing malformed CIDR strings through custom code instead of net.ParseCIDR; storing IPs in a format that lost its bytes before calling this helper.
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
- transforming last address of range: %w
- unexpected len %d for %s
- while parsing capi whitelist file '%s': %w
- auto_register: failed to parse allowed range '%s': %w
- unable to convert '%s' to int: %w: %w
AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06).
Data as JSON: /api/errors/8489e74d10cdc915.
Report an issue: GitHub.