kubernetes/kops · error

expected protocol[:portspec] in firewall rule %q

Error message

expected protocol[:portspec] in firewall rule %q

What it means

parseFirewallAllowed() splits a firewall 'allowed' entry on ':' and expects the form protocol[:portspec]. This error fires when splitting yields more than two tokens (or zero), e.g. a stray colon or malformed string, so the rule cannot be parsed into a compute.FirewallAllowed.

Source

Thrown at upup/pkg/fi/cloudup/gcetasks/firewallrule.go:157

		}
	}

	return nil
}

func (_ *FirewallRule) CheckChanges(a, e, changes *FirewallRule) error {
	if e.Network == nil {
		return fi.RequiredField("Network")
	}
	return nil
}

func parseFirewallAllowed(rule string) (*compute.FirewallAllowed, error) {
	o := &compute.FirewallAllowed{}

	tokens := strings.Split(rule, ":")
	if len(tokens) < 1 || len(tokens) > 2 {
		return nil, fmt.Errorf("expected protocol[:portspec] in firewall rule %q", rule)
	}

	o.IPProtocol = tokens[0]
	if len(tokens) == 1 {
		return o, nil
	}

	o.Ports = []string{tokens[1]}
	return o, nil
}

func serializeFirewallAllowed(r *compute.FirewallAllowed) string {
	if len(r.Ports) == 0 {
		return r.IPProtocol
	}

	var tokens []string
	for _, ports := range r.Ports {

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Fix the allowed entry to contain at most one colon: 'tcp' or 'tcp:22' or 'tcp:3000-4000'.
  2. For multiple port ranges, use separate entries or a comma-joined portspec as supported by the spec, not extra colons.
  3. Check the cluster spec YAML for stray characters in the firewall section.

Example fix

// before
rule: "tcp:80:443"
// after
rule: "tcp:80,443"
Defensive patterns

Strategy: validation

Validate before calling

func validateFirewallAllowed(rule string) error {
  parts := strings.Split(rule, ":")
  if len(parts) < 1 || len(parts) > 2 {
    return fmt.Errorf("rule %q must be protocol[:portspec]", rule)
  }
  if len(parts) == 2 {
    for _, p := range strings.Split(parts[1], ",") {
      if !portSpecRe.MatchString(p) {
        return fmt.Errorf("bad port %q in %q", p, rule)
      }
    }
  }
  return nil
}
var portSpecRe = regexp.MustCompile(`^\d+(-\d+)?$`)

Prevention

When it happens

Trigger: An allowed rule string in the cluster spec contains more than one ':' character, e.g. 'tcp:80:90' or 'tcp:'-like typos; strings.Split always returns at least one token, so len>2 is the only real trigger.

Common situations: Typos in port ranges ('tcp:1-65535:extra'), copy-pasted rules from other clouds, accidental trailing colons, or concatenating spec fragments.

Related errors


AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05). Data as JSON: /api/errors/91a6e1560fd6e9ba. Report an issue: GitHub.