slackhq/nebula · error
%s rule #%v; %s %s
Error message
%s rule #%v; %s %s
What it means
After proto validation, AddFirewallRulesFromConfig parses the rule's port (or ICMP code) value into startPort/endPort. If that parsing fails, the error is wrapped as "<table> rule #<index>; <port|code> <err>" indicating which field failed and why.
Source
Thrown at firewall.go:384
startPort, endPort, err = parsePort(sPort)
case "tcp":
proto = iputil.IPProtocolTCP
startPort, endPort, err = parsePort(sPort)
case "udp":
proto = iputil.IPProtocolUDP
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",View on GitHub (pinned to dd8f660c0a)
Solutions
- Use a numeric port string in 0-65535 (e.g. "443"); use "any" for all ports.
- For ICMP rules, ensure "code" is a valid numeric code and remove "port".
- Split multi-port needs into multiple rules.
Example fix
// before (config) - port: https proto: tcp // after - port: 443 proto: tcp
Defensive patterns
Strategy: validation
Validate before calling
func validatePortField(rules []map[string]any) error {
for i, r := range rules {
for _, k := range []string{"port", "code"} {
v, ok := r[k].(string)
if !ok || v == "" || v == "any" { continue }
n, err := strconv.Atoi(v)
if err != nil || n < 0 || n > 65535 {
return fmt.Errorf("rule #%d: %s %q must be 0-65535 or \"any\"", i, k, v)
}
}
}
return nil
} Try / catch
if err := fw.AddFirewallRulesFromConfig(l, "inbound", rules); err != nil {
var portErr bool
if strings.Contains(err.Error(), " port ") || strings.Contains(err.Error(), " code ") {
portErr = true
}
if portErr { log.Fatalf("numeric port/code required: %v", err) }
return err
} Prevention
- Always use numeric port literals, never service names like "https".
- Quote port values in YAML so they decode as strings.
- Keep ports in 1-65535; use "any" for wildcard.
When it happens
Trigger: A rule with a non-numeric or out-of-range port/code, e.g. port: "https", port: "70000", or port: "80-90" where ranged/shorthand forms are not accepted here.
Common situations: Using service names instead of numeric ports, unquoted YAML values interpreted oddly, copy-pasting port ranges, or typos in the port number.
Related errors
- ErrInvalidLocalIP
- unknown protocol %v
- %s failed to parse, should be an array of rules
- %s rule #%v; %s
- %s rule #%v; only one of port or code should be provided
AI-assisted analysis of slackhq/nebula@dd8f660c0a (2026-09-03).
Data as JSON: /api/errors/77502146a60475fa.
Report an issue: GitHub.