slackhq/nebula · error
%s rule #%v; cidr did not parse; %s
Error message
%s rule #%v; cidr did not parse; %s
What it means
AddFirewallRulesFromConfig validates each rule's cidr with netip.ParsePrefix unless the value is empty or "any". A malformed CIDR (missing prefix length, bad IP, invalid mask) produces this wrapped error naming the table, rule index, and parse failure.
Source
Thrown at firewall.go:390
startPort, endPort, err = parsePort(sPort)
case "icmp":
proto = iputil.IPProtocolICMP
startPort = firewall.PortAny
endPort = firewall.PortAny
if sPort != "" {
l.Warn("ignoring port specification for ICMP firewall rule", "port", sPort)
}
default:
return fmt.Errorf("%s rule #%v; proto was not understood; `%s`", table, i, r.Proto)
}
if err != nil {
return fmt.Errorf("%s rule #%v; %s %s", table, i, errPort, err)
}
if r.Cidr != "" && r.Cidr != "any" {
_, err = netip.ParsePrefix(r.Cidr)
if err != nil {
return fmt.Errorf("%s rule #%v; cidr did not parse; %s", table, i, err)
}
}
if r.LocalCidr != "" && r.LocalCidr != "any" {
_, err = netip.ParsePrefix(r.LocalCidr)
if err != nil {
return fmt.Errorf("%s rule #%v; local_cidr did not parse; %s", table, i, err)
}
}
if warning := r.sanity(); warning != nil {
l.Warn("firewall rule sanity check",
"table", table,
"rule", i,
"warning", warning,
)
}
View on GitHub (pinned to dd8f660c0a)
Solutions
- Provide a valid CIDR prefix, e.g. "10.0.0.0/24"; use "/32" for a single IPv4 host.
- Use "any" as the value if the rule should match any remote CIDR.
- Validate locally with netip.ParsePrefix (or an online CIDR checker) before deploying the config.
Example fix
// before (config) - cidr: 10.0.0.0 proto: any // after - cidr: 10.0.0.0/24 proto: any
Defensive patterns
Strategy: validation
Validate before calling
import "netip"
func validateCidrField(rules []map[string]any, key string) error {
for i, r := range rules {
v, _ := r[key].(string)
if v == "" || v == "any" { continue }
if _, err := netip.ParsePrefix(v); err != nil {
return fmt.Errorf("rule #%d: %s %q is not a valid CIDR: %v", i, key, v, err)
}
}
return nil
} Try / catch
if err := fw.AddFirewallRulesFromConfig(l, "inbound", rules); err != nil {
if strings.Contains(err.Error(), "cidr did not parse") {
log.Fatalf("fix CIDR (include /prefix length): %v", err)
}
return err
} Prevention
- Always include a prefix length (/24, /32, /64); a bare IP is not a CIDR.
- Use "any" instead of 0.0.0.0/0 if that is the intent.
- Run netip.ParsePrefix on all cidr fields as a pre-deploy config test.
When it happens
Trigger: A rule with cidr like "10.0.0.0" (missing /prefix), "10.0.0.0/33", "hostnames don't work", or an IPv6/IPv4 mismatch, and not "any".
Common situations: Omitting the prefix length out of habit, using a hostname or IP list instead of a single CIDR, or writing single-host IPs without /32.
Related errors
- %s rule #%v; local_cidr did not parse; %s
- ErrInvalidLocalIP
- unknown protocol %v
- %s failed to parse, should be an array of rules
- %s rule #%v; %s
AI-assisted analysis of slackhq/nebula@dd8f660c0a (2026-09-03).
Data as JSON: /api/errors/f0cf4f79f64bae7e.
Report an issue: GitHub.