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

  1. Add a concrete port, e.g. tcp/443
  2. Use 'all' instead of 'tcp/' when all traffic is intended
  3. 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

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


AI-assisted analysis of netbirdio/netbird@93e97f4bf1 (2026-08-16). Data as JSON: /api/errors/6c82ac7440522a23. Report an issue: GitHub.