cilium/cilium · error

too many ports, the max is %d

Error message

too many ports, the max is %d

What it means

PortRule.Validate enforces a hard limit of maxPorts ports per PortRule. A policy that lists more than this number of entries in a single port rule is rejected to keep the policy manageable and proxy rules bounded. The error reports the configured maximum.

Source

Thrown at pkg/policy/api/rule_validation.go:643

// It is not allowed to configure an ingress listener, but we still
// have some unit tests relying on this. So, allow overriding this check in the unit tests.
var TestAllowIngressListener = false

func (pr *PortRule) Validate(ingress bool) error {
	hasDNSRules := pr.Rules != nil && len(pr.Rules.DNS) > 0
	if ingress && hasDNSRules {
		return fmt.Errorf("DNS rules are not allowed on ingress")
	}

	if len(pr.ServerNames) > 0 && !pr.Rules.IsEmpty() && pr.TerminatingTLS == nil {
		return fmt.Errorf("ServerNames are not allowed with L7 rules without TLS termination")
	}
	if slices.Contains(pr.ServerNames, "") {
		return errEmptyServerName
	}

	if len(pr.Ports) > maxPorts {
		return fmt.Errorf("too many ports, the max is %d", maxPorts)
	}
	haveZeroPort := false
	for i := range pr.Ports {
		var isZero bool
		var err error
		if isZero, err = pr.Ports[i].Validate(hasDNSRules); err != nil {
			return err
		}
		if isZero {
			haveZeroPort = true
		}
		// DNS L7 rules can be TCP, UDP or ANY, all others are TCP only.
		switch {
		case pr.Rules.IsEmpty(), hasDNSRules:
			// nothing to do if no rules OR they are DNS rules (note the comma above)
		case pr.Ports[i].Protocol != ProtoTCP:
			return fmt.Errorf("L7 rules can only apply to TCP (not %s) except for DNS rules", pr.Ports[i].Protocol)
		}

View on GitHub (pinned to ac7b90affa)

Solutions

  1. Split the policy into multiple NetworkPolicy rules, each with at most maxPorts port entries.
  2. Use cidr+port rules more coarsely, or rely on label-based selectors instead of enumerating ports.
  3. Consolidate adjacent ports where the datapath allows (e.g. use a range if supported via toPorts ports with endPort).
  4. Generate the policy programmatically and enforce the maxPorts cap in your generator.

Example fix

// before: one rule with 50+ ports
- toPorts:
  - ports:
    - port: "1000"
    - port: "1001"
    # ... 50 more
// after: split across rules, or use endPort range
- toPorts:
  - ports:
    - port: "1000"
      endPort: "1100"
Defensive patterns

Strategy: validation

Validate before calling

const maxPorts = 40 // match library constant
func checkPortCount(pr api.PortRule) error {
    if len(pr.Ports) > maxPorts {
        return fmt.Errorf("port rule has %d ports, max is %d", len(pr.Ports), maxPorts)
    }
    return nil
}

Type guard

func exceedsPortLimit(pr api.PortRule, limit int) bool { return len(pr.Ports) > limit }

Prevention

When it happens

Trigger: Calling PortRule.Validate with len(pr.Ports) > maxPorts — i.e. one toPorts entry (or generated PortRule) enumerating more than the allowed number of ports, typically from programmatically generated policies listing many ports.

Common situations: Auto-generated policies from service inventories enumerating dozens of ports; users trying to whitelist large port ranges by listing each port individually; YAML merge producing concatenated port lists.

Related errors


AI-assisted analysis of cilium/cilium@ac7b90affa (2026-08-31). Data as JSON: /api/errors/02f7578a20d86901. Report an issue: GitHub.