{"record":{"id":"a9ec354bd8062d1a","repo":"crowdsecurity/crowdsec","slug":"transforming-last-address-of-range-w","errorCode":null,"errorMessage":"transforming last address of range: %w","messagePattern":"transforming last address of range: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/types/ip.go","lineNumber":71,"sourceCode":"\tif err != nil {\n\t\treturn -1, 0, 0, 0, 0, fmt.Errorf(\"invalid ip address '%s': %w\", anyIP, err)\n\t}\n\n\treturn sz, start, end, start, end, nil\n}\n\n/*size (16|4), nw_start, suffix_start, nw_end, suffix_end, error*/\nfunc Range2Ints(network net.IPNet) (int, int64, int64, int64, int64, error) {\n\tszStart, nwStart, sfxStart, err := IP2Ints(network.IP)\n\tif err != nil {\n\t\treturn -1, 0, 0, 0, 0, fmt.Errorf(\"converting first ip in range: %w\", err)\n\t}\n\n\tlastAddr := LastAddress(network)\n\n\tszEnd, nwEnd, sfxEnd, err := IP2Ints(lastAddr)\n\tif err != nil {\n\t\treturn -1, 0, 0, 0, 0, fmt.Errorf(\"transforming last address of range: %w\", err)\n\t}\n\n\tif szEnd != szStart {\n\t\treturn -1, 0, 0, 0, 0, fmt.Errorf(\"inconsistent size for range first(%d) and last(%d) ip\", szStart, szEnd)\n\t}\n\n\treturn szStart, nwStart, sfxStart, nwEnd, sfxEnd, nil\n}\n\nfunc uint2int(u uint64) int64 {\n\tvar ret int64\n\tif u == math.MaxInt64 {\n\t\tret = 0\n\t} else if u == math.MaxUint64 {\n\t\tret = math.MaxInt64\n\t} else if u > math.MaxInt64 {\n\t\tu -= math.MaxInt64\n\t\tret = int64(u)","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/types/ip.go#L53-L89","documentation":"After converting the first address of a net.IPNet, Range2Ints computes the last address via LastAddress and converts it too. If IP2Ints fails on the last address, the error is wrapped with this message. LastAddress ORs the hostmask into the base IP, so failure here means the resulting broadcast address is nil or has an invalid byte length.","triggerScenarios":"Range2Ints (or Addr2Ints with a CIDR string) receiving a net.IPNet whose Mask is the wrong length for its IP (e.g. a 4-byte mask on a 16-byte IPv6 IP), causing LastAddress to build a malformed/short net.IP that IP2Ints rejects.","commonSituations":"Manually constructing net.IPNet with mismatched IP/Mask lengths (mixing To4 IPs with 16-byte masks or vice versa); migrating code from IPv4-only assumptions to IPv6 networks; deserialized/persisted IPNet values with corrupted fields.","solutions":["Ensure the Mask length matches the IP family: use net.CIDRMask(ones, 32) for IPv4 and net.CIDRMask(ones, 128) for IPv6","Parse CIDR strings with net.ParseCIDR instead of hand-building net.IPNet so Mask/IP stay consistent","Check the wrapped error: the last-address length printed there reveals the mismatch","For custom ranges, call network.IP.To4()/To16() first and derive the mask from the same representation"],"exampleFix":"// before\nipnet := net.IPNet{IP: net.ParseIP(\"2001:db8::\"), Mask: net.CIDRMask(24, 32)} // 4-byte mask on IPv6\n_, _, _, _, _, err := types.Range2Ints(ipnet)\n// after\nipnet := net.IPNet{IP: net.ParseIP(\"2001:db8::\"), Mask: net.CIDRMask(64, 128)}\n_, _, _, _, _, err := types.Range2Ints(ipnet)","handlingStrategy":"validation","validationCode":"func maskMatchesIP(n net.IPNet) bool {\n    if n.IP.To4() != nil { return len(n.Mask) == net.IPv4len }\n    return len(n.Mask) == net.IPv6len\n}","typeGuard":"func consistentIPNet(n net.IPNet) bool { return (n.IP.To4() != nil) == (len(n.Mask) == net.IPv4len) }","tryCatchPattern":null,"preventionTips":["Derive masks with net.CIDRMask(ones, 32) for IPv4 and net.CIDRMask(ones, 128) for IPv6","Never mix To4() IPs with 16-byte masks or vice versa","Prefer string parsing (ParseCIDR) over hand-built IPNet structs"],"tags":["ip","cidr","mask-mismatch","parsing"],"backgroundTag":"invalid-argument-value","analyzedSha":"909b5157986a2b2c2163300fdaef5ed01289f7d2","analyzedAt":"2026-09-06T12:27:26.012Z","contentChangedAt":"2026-09-06T12:27:26.012Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}