kubernetes/kops · error

cannot parse rule %q

Error message

cannot parse rule %q

What it means

ParseRemovalRule emits this when the from-port in a `port=N` / `port=N:M` removal rule cannot be converted to an integer with strconv.Atoi. It is the first of the port-parse failure paths. The error deliberately discards the strconv detail and just echoes the rule string.

Source

Thrown at upup/pkg/fi/cloudup/awstasks/securitygroup.go:412

	Matches(permission *ec2types.SecurityGroupRule) bool
}

// ParseRemovalRule parses our removal rule DSL into a RemovalRule
func ParseRemovalRule(rule string) (RemovalRule, error) {
	rule = strings.TrimSpace(rule)
	tokens := strings.Split(rule, "=")

	// Simple little language:
	//   port=N matches rules that filter (only) by port=N
	//
	// Note this language is internal, so isn't required to be stable

	if len(tokens) == 2 {
		if tokens[0] == "port" {
			ports := strings.SplitN(tokens[1], ":", 2)
			fromPort, err := strconv.Atoi(ports[0])
			if err != nil {
				return nil, fmt.Errorf("cannot parse rule %q", rule)
			}
			toPort := fromPort
			if len(ports) > 1 {
				toPort, err = strconv.Atoi(ports[1])
				if err != nil {
					return nil, fmt.Errorf("cannot parse rule %q", rule)
				}
			}

			return &PortRemovalRule{
				FromPort: fromPort,
				ToPort:   toPort,
			}, nil
		} else {
			return nil, fmt.Errorf("cannot parse rule %q", rule)
		}
	}
	return nil, fmt.Errorf("cannot parse rule %q", rule)

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Rewrite the rule with numeric ports: `port=22` or a range `port=22:23` (colon, not hyphen)
  2. Confirm no stray characters (quotes, spaces, tabs) inside the value in the cluster spec
  3. Run `kops toolbox`/dry-run (`kops update cluster` without --yes) to validate the spec before applying

Example fix

// before
removeExtraRules: ["port=22-25"]
// after
removeExtraRules: ["port=22:25"]
Defensive patterns

Strategy: validation

Validate before calling

func validPortRule(s string) bool {
  parts := strings.SplitN(s, "=", 2)
  if len(parts) != 2 || parts[0] != "port" { return false }
  ports := strings.SplitN(parts[1], ":", 2)
  if _, err := strconv.Atoi(ports[0]); err != nil { return false }
  if len(ports) > 1 {
    if _, err := strconv.Atoi(ports[1]); err != nil { return false }
  }
  return true
}

Prevention

When it happens

Trigger: removeExtraRules entry like `port=abc`, `port=ssh`, `port=` (empty after '='), or `port=22-23` where tokens[1] split on ':' yields "22-23" which is not an integer.

Common situations: Using '-' instead of ':' as the range separator in port=22-23 (Atoi fails on "22-23" as from-port); specifying a service name instead of a number; accidental non-ASCII/whitespace characters in the spec value.

Related errors


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