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

  1. Write the value in CIDR form: "203.0.113.0/24", "198.51.100.7/32", "2001:db8::/32".
  2. If you meant a single address, move the value to the "ips" array (bare IPs are rejected by ParsePrefix).
  3. Fix the prefix length: IPv4 allows /0–/32, IPv6 /0–/128; remove lengths like /33.
  4. Validate locally before editing: `python3 -c "import ipaddress; ipaddress.ip_network('VALUE')"`.
  5. 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

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


AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06). Data as JSON: /api/errors/addb02a85995da11. Report an issue: GitHub.