netbirdio/netbird · error
empty port
Error message
empty port
What it means
parsePort rejects an empty port string. It is reached from ParseRuleString when the rule has a protocol, a '/', and nothing after it (e.g. "tcp/"), because strings.Split keeps the empty segment and TrimSpace leaves it empty. Valid ports must parse as integers in 1-65535.
Source
Thrown at shared/management/types/policy.go:258
}
if start > end {
return RulePortRange{}, fmt.Errorf("invalid port range: start %d > end %d", start, end)
}
return RulePortRange{Start: uint16(start), End: uint16(end)}, nil
}
p, err := parsePort(portStr)
if err != nil {
return RulePortRange{}, err
}
return RulePortRange{Start: uint16(p), End: uint16(p)}, nil
}
func parsePort(portStr string) (int, error) {
if portStr == "" {
return 0, errors.New("empty port")
}
p, err := strconv.Atoi(portStr)
if err != nil {
return 0, fmt.Errorf("invalid port %q: %w", portStr, err)
}
if p < 1 || p > 65535 {
return 0, fmt.Errorf("port out of range (1–65535): %d", p)
}
return p, nil
}
View on GitHub (pinned to 93e97f4bf1)
Solutions
- Add a concrete port, e.g. tcp/443
- Use 'all' instead of 'tcp/' when all traffic is intended
- Validate generated rule strings before submitting them to the API
Example fix
// before
proto, ports, err := types.ParseRuleString("tcp/")
// after
proto, ports, err := types.ParseRuleString("tcp/443") Defensive patterns
Strategy: validation
Validate before calling
parts := strings.Split(rule, "/")
if len(parts) == 2 && strings.TrimSpace(parts[1]) == "" {
return fmt.Errorf("rule %q is missing its port", rule)
} Type guard
func hasPortSegment(rule string) bool {
parts := strings.Split(strings.TrimSpace(rule), "/")
return len(parts) != 2 || strings.TrimSpace(parts[1]) != ""
} Try / catch
if _, _, err := types.ParseRuleString(rule); err != nil {
if err.Error() == "empty port" {
// unfilled template placeholder; surface config error to the user
}
} Prevention
- Fail template rendering when port variables are unset
- Validate generated rule strings before API submission
- Trim inputs and reject trailing slashes at the form layer
When it happens
Trigger: Rules like "tcp/" or "udp/ " with a missing or whitespace-only port; template strings such as tcp/${PORT} with the variable unset.
Common situations: Unfilled template placeholders in generated configs; truncated rule strings from imports; trailing-slash typos.
Related errors
- invalid rule format: expected protocol/port or protocol/port
- icmp does not accept ports; use 'icmp' without '/…'
- invalid duration format: %v
- no keys found in bundle
- failed to decode PEM data
AI-assisted analysis of netbirdio/netbird@93e97f4bf1 (2026-08-16).
Data as JSON: /api/errors/6c82ac7440522a23.
Report an issue: GitHub.