{"record":{"id":"5363159243e7ed7b","repo":"crowdsecurity/crowdsec","slug":"invalid-ip-address-s","errorCode":null,"errorMessage":"invalid ip address '%s'","messagePattern":"invalid ip address '(.+?)'","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/types/ip.go","lineNumber":49,"sourceCode":"\t\tip[1]|^n.Mask[1],\n\t\tip[2]|^n.Mask[2],\n\t\tip[3]|^n.Mask[3])\n}\n\n/*returns a range for any ip or range*/\nfunc Addr2Ints(anyIP string) (int, int64, int64, int64, int64, error) {\n\tif strings.Contains(anyIP, \"/\") {\n\t\t_, net, err := net.ParseCIDR(anyIP)\n\t\tif err != nil {\n\t\t\treturn -1, 0, 0, 0, 0, fmt.Errorf(\"invalid ip range '%s': %w\", anyIP, err)\n\t\t}\n\n\t\treturn Range2Ints(*net)\n\t}\n\n\tip := net.ParseIP(anyIP)\n\tif ip == nil {\n\t\treturn -1, 0, 0, 0, 0, fmt.Errorf(\"invalid ip address '%s'\", anyIP)\n\t}\n\n\tsz, start, end, err := IP2Ints(ip)\n\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)","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/types/ip.go#L31-L67","documentation":"Addr2Ints parses non-CIDR input with net.ParseIP; if it returns nil the string is neither a valid IPv4 nor IPv6 address, producing \"invalid ip address '%s'\". This is the plain-address branch used by NewRange and range tests. No underlying net error exists because ParseIP only signals failure by returning nil.","triggerScenarios":"Calling Addr2Ints/NewRange with a slash-free string that net.ParseIP rejects — hostname, empty string, '1.2.3.4:80', '01.02.03.04' (leading zeros), truncated address.","commonSituations":"Passing a hostname instead of an IP; extracting the IP from a log line without stripping the port; leading-zero IPv4 octets (rejected by Go's ParseIP); empty field from a split that produced no data.","solutions":["Ensure the input is a bare valid IP (strip ports, resolve hostnames with net.LookupIP first)","Validate with net.ParseIP or netip.ParseAddr before calling Addr2Ints","Check for empty or whitespace-only input coming from log parsing/splitting","Remove leading zeros from IPv4 octets"],"exampleFix":"// before\nhost, port, _ := net.SplitHostPort(line)\nip := strings.TrimSpace(host) + \":80\"   // port still attached\n// after\nip, err := types.Addr2Ints(strings.TrimSpace(host))","handlingStrategy":"validation","validationCode":"import \"net/netip\"\nfunc validIP(s string) bool {\n  _, err := netip.ParseAddr(strings.TrimSpace(s))\n  return err == nil\n}","typeGuard":null,"tryCatchPattern":"r, err := types.NewRange(input)\nif err != nil {\n  if strings.Contains(err.Error(), \"invalid ip address\") && !strings.Contains(input, \"/\") {\n    return fmt.Errorf(\"rejecting non-ip %q\", input)\n  }\n  return err\n}","preventionTips":["Strip ports and surrounding whitespace before parsing","Resolve hostnames to IPs first; never pass hostnames to Addr2Ints","Avoid leading zeros in IPv4 octets","Check for empty fields from string splitting"],"tags":["go","network","ip","parsing"],"backgroundTag":"invalid-argument-format","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"}