{"record":{"id":"f0cf4f79f64bae7e","repo":"slackhq/nebula","slug":"s-rule-v-cidr-did-not-parse-s","errorCode":null,"errorMessage":"%s rule #%v; cidr did not parse; %s","messagePattern":"(.+?) rule #(.+?); cidr did not parse; (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"firewall.go","lineNumber":390,"sourceCode":"\t\t\tstartPort, endPort, err = parsePort(sPort)\n\t\tcase \"icmp\":\n\t\t\tproto = iputil.IPProtocolICMP\n\t\t\tstartPort = firewall.PortAny\n\t\t\tendPort = firewall.PortAny\n\t\t\tif sPort != \"\" {\n\t\t\t\tl.Warn(\"ignoring port specification for ICMP firewall rule\", \"port\", sPort)\n\t\t\t}\n\t\tdefault:\n\t\t\treturn fmt.Errorf(\"%s rule #%v; proto was not understood; `%s`\", table, i, r.Proto)\n\t\t}\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"%s rule #%v; %s %s\", table, i, errPort, err)\n\t\t}\n\n\t\tif r.Cidr != \"\" && r.Cidr != \"any\" {\n\t\t\t_, err = netip.ParsePrefix(r.Cidr)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"%s rule #%v; cidr did not parse; %s\", table, i, err)\n\t\t\t}\n\t\t}\n\n\t\tif r.LocalCidr != \"\" && r.LocalCidr != \"any\" {\n\t\t\t_, err = netip.ParsePrefix(r.LocalCidr)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"%s rule #%v; local_cidr did not parse; %s\", table, i, err)\n\t\t\t}\n\t\t}\n\n\t\tif warning := r.sanity(); warning != nil {\n\t\t\tl.Warn(\"firewall rule sanity check\",\n\t\t\t\t\"table\", table,\n\t\t\t\t\"rule\", i,\n\t\t\t\t\"warning\", warning,\n\t\t\t)\n\t\t}\n","sourceCodeStart":372,"sourceCodeEnd":408,"githubUrl":"https://github.com/slackhq/nebula/blob/dd8f660c0ac37903ec4080ca4d3c861ba9342ceb/firewall.go#L372-L408","documentation":"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.","triggerScenarios":"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\".","commonSituations":"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.","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."],"exampleFix":"// before (config)\n- cidr: 10.0.0.0\n  proto: any\n// after\n- cidr: 10.0.0.0/24\n  proto: any","handlingStrategy":"validation","validationCode":"import \"netip\"\n\nfunc validateCidrField(rules []map[string]any, key string) error {\n    for i, r := range rules {\n        v, _ := r[key].(string)\n        if v == \"\" || v == \"any\" { continue }\n        if _, err := netip.ParsePrefix(v); err != nil {\n            return fmt.Errorf(\"rule #%d: %s %q is not a valid CIDR: %v\", i, key, v, err)\n        }\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"if err := fw.AddFirewallRulesFromConfig(l, \"inbound\", rules); err != nil {\n    if strings.Contains(err.Error(), \"cidr did not parse\") {\n        log.Fatalf(\"fix CIDR (include /prefix length): %v\", err)\n    }\n    return err\n}","preventionTips":["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."],"tags":["firewall","configuration","cidr","networking"],"backgroundTag":"invalid-cidr-notation","analyzedSha":"dd8f660c0ac37903ec4080ca4d3c861ba9342ceb","analyzedAt":"2026-09-03T11:13:55.444Z","contentChangedAt":"2026-09-03T11:13:55.444Z","schemaVersion":2},"datasetVersion":"2026-09-10T17:17:09.494Z"}