{"record":{"id":"f3389163d49ffa97","repo":"crowdsecurity/crowdsec","slug":"unexpected-len-d-for-s","errorCode":null,"errorMessage":"unexpected len %d for %s","messagePattern":"unexpected len (.+?) for (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/types/ip.go","lineNumber":117,"sourceCode":"func IP2Ints(pip net.IP) (int, int64, int64, error) {\n\tvar ip_nw, ip_sfx uint64\n\n\tpip4 := pip.To4()\n\tpip16 := pip.To16()\n\n\tif pip4 != nil {\n\t\tip_nw32 := binary.BigEndian.Uint32(pip4)\n\t\treturn 4, uint2int(uint64(ip_nw32)), uint2int(ip_sfx), nil\n\t}\n\n\tif pip16 != nil {\n\t\tip_nw = binary.BigEndian.Uint64(pip16[0:8])\n\t\tip_sfx = binary.BigEndian.Uint64(pip16[8:16])\n\n\t\treturn 16, uint2int(ip_nw), uint2int(ip_sfx), nil\n\t}\n\n\treturn -1, 0, 0, fmt.Errorf(\"unexpected len %d for %s\", len(pip), pip)\n}\n","sourceCodeStart":99,"sourceCodeEnd":119,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/types/ip.go#L99-L119","documentation":"IP2Ints converts a net.IP to (size, network-int, suffix-int) by first trying To4(), then To16(). If both conversions return nil, the IP has an unsupported/invalid byte representation and this error is returned with the actual length. This happens for nil net.IP or IPs whose internal representation is empty.","triggerScenarios":"Calling IP2Ints directly (or via Range2Ints/Addr2Ints) with a nil net.IP, a net.IP built from an empty or zero-length byte slice, or a struct where the IP field was never populated.","commonSituations":"Parsing empty strings from config (net.ParseIP(\"\") returns nil); a whitelist/blacklist entry that is a hostname rather than an IP reaching this code; IPs returned nil from map lookups or failed DNS resolution; zero-value net.IP variables.","solutions":["Validate before calling: if ip == nil || ip.To16() == nil { return/parse again }","Use net.ParseIP on the original string and handle the nil return at parse time","Check upstream parsing: ensure hostnames are resolved (or rejected) before reaching IP conversion","Read the error's len/pip values — len 0 with empty IP almost always means a nil or unset net.IP"],"exampleFix":"// before\nip := net.ParseIP(entry) // entry is \"example.com\" -> nil\nsz, _, _, err := types.IP2Ints(ip)\n// after\nip := net.ParseIP(entry)\nif ip == nil || ip.To16() == nil {\n    return fmt.Errorf(\"'%s' is not a valid IP address\", entry)\n}\nsz, _, _, err := types.IP2Ints(ip)","handlingStrategy":"validation","validationCode":"if ip == nil || ip.To16() == nil { return fmt.Errorf(\"not a valid IP: %q\", raw) }","typeGuard":"func isUsableIP(ip net.IP) bool { return ip != nil && ip.To4() != nil || ip.To16() != nil }","tryCatchPattern":"if err != nil {\n    if strings.Contains(err.Error(), \"unexpected len\") {\n        // fall back: re-parse the raw string with net.ParseIP and surface it to the user\n    }\n    return err\n}","preventionTips":["Check net.ParseIP for nil before using its result","Reject empty strings and hostnames before IP conversion","Handle DNS-resolution failures explicitly instead of passing nil IPs"],"tags":["ip","parsing","nil","validation"],"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"}