crowdsecurity/crowdsec · error
invalid CIDR range '%s' for bot entry '%s' in %s: %w
Error message
invalid CIDR range '%s' for bot entry '%s' in %s: %w
What it means
botFileInit parses each element of the entry's "ranges" array with netip.ParsePrefix and stores the masked prefix. This error is thrown when a listed range is not valid CIDR notation. Note that a bare IP like "1.2.3.4" is also rejected by ParsePrefix — ranges require the /prefix-length form.
Source
Thrown at pkg/exprhelpers/botfile.go:97
entry.pathRegexes = append(entry.pathRegexes, re)
}
entry.ipSet = make(map[netip.Addr]struct{}, len(entry.IPs))
for _, ip := range entry.IPs {
addr, err := netip.ParseAddr(ip)
if err != nil {
return fmt.Errorf("invalid IP '%s' for bot entry '%s' in %s: %w", ip, entry.Name, filename, err)
}
entry.ipSet[addr.Unmap()] = struct{}{}
}
for _, r := range entry.Ranges {
prefix, err := netip.ParsePrefix(r)
if err != nil {
return fmt.Errorf("invalid CIDR range '%s' for bot entry '%s' in %s: %w", r, entry.Name, filename, err)
}
entry.prefixes = append(entry.prefixes, prefix.Masked())
}
for _, p := range entry.RDNS {
// an empty pattern matches every PTR-confirmed host: almost
// certainly a mistake, reject it
if p == "" {
return fmt.Errorf("empty rdns pattern for bot entry '%s' in %s", entry.Name, filename)
}
re, err := compileBotRegex(p)
if err != nil {
return fmt.Errorf("invalid rdns regex '%s' for bot entry '%s' in %s: %w", p, entry.Name, filename, err)
}
entry.rdnsRegexes = append(entry.rdnsRegexes, re)View on GitHub (pinned to 909b515798)
Solutions
- Write the value in CIDR form: "203.0.113.0/24", "198.51.100.7/32", "2001:db8::/32".
- If you meant a single address, move the value to the "ips" array (bare IPs are rejected by ParsePrefix).
- Fix the prefix length: IPv4 allows /0–/32, IPv6 /0–/128; remove lengths like /33.
- Validate locally before editing: `python3 -c "import ipaddress; ipaddress.ip_network('VALUE')"`.
- Split comma-separated networks into separate array elements.
Example fix
// before
{"name":"cloud","ranges":["10.0.0.0","2001:db8::/129"]}
// after
{"name":"cloud","ranges":["10.0.0.0/8","2001:db8::/32"]} Defensive patterns
Strategy: validation
Validate before calling
for _, r := range entry.Ranges {
if _, err := netip.ParsePrefix(strings.TrimSpace(r)); err != nil {
// reject before FileInit
}
}
valid := err == nil Try / catch
if err := exprhelpers.FileInit(botFile, "bots"); err != nil {
if strings.Contains(err.Error(), "invalid CIDR range") {
log.Errorf("bad ranges element: %v", err)
}
return err
} Prevention
- Always write ranges as address/length CIDR, including /32 and /128 for single hosts.
- Validate prefixes with netip.ParsePrefix (or ipaddress.ip_network) in CI.
- Put bare single IPs in the ips array instead of ranges.
- Split comma-joined networks into separate JSON array elements.
When it happens
Trigger: A bots JSONL entry contains "ranges":[...] with an element missing the prefix length ("10.0.0.0"), an invalid length ("10.0.0.0/33"), a hostname, or any other non-CIDR string. netip.ParsePrefix fails and the error wraps its message.
Common situations: Copy-pasting single IPs into ranges instead of ips; omitting "/32" or "/128" when listing individual hosts as ranges; typo in prefix length; using IPv6 notation incorrectly (e.g. "/129"); comma-separated multiple networks in one element.
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
- unable to convert '%s' to int: %w: %w
- unable to convert '%s' to int: %w
- invalid ip range '%s': %w
- missing allowed_ranges value for api.server.auto_register
- out of bound gid
AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06).
Data as JSON: /api/errors/addb02a85995da11.
Report an issue: GitHub.