kubernetes/kops · error

invalid subnet %q CIDR: %q

Error message

invalid subnet %q CIDR: %q

What it means

This error is thrown by kOps' automatic subnet CIDR assignment logic when a subnet in the cluster spec declares a CIDR that net.ParseCIDR cannot parse. It aborts cluster spec validation so that a malformed CIDR never reaches cloud provisioning.

Source

Thrown at upup/pkg/fi/cloudup/subnets.go:140

	_, cidr, err := net.ParseCIDR(c.Spec.Networking.NetworkCIDR)
	if err != nil {
		return fmt.Errorf("Invalid NetworkCIDR: %q", c.Spec.Networking.NetworkCIDR)
	}

	// We split the network range into 2, 4 or 8 subnets
	// But we then reserve the lowest one for the private block
	// (and we split _that_ into 8 further subnets, leaving the first one unused/for future use)

	var bigSubnets []*kops.ClusterSubnetSpec
	var littleSubnets []*kops.ClusterSubnetSpec

	var reserved []*net.IPNet
	for i := range c.Spec.Networking.Subnets {
		subnet := &c.Spec.Networking.Subnets[i]
		if subnet.CIDR != "" {
			_, cidrSubnet, err := net.ParseCIDR(subnet.CIDR)
			if err != nil {
				return fmt.Errorf("invalid subnet %q CIDR: %q", subnet.Name, subnet.CIDR)
			}
			// Skip additional subnets
			if !cidr.Contains(cidrSubnet.IP) {
				continue
			}
		}
		switch subnet.Type {
		case kops.SubnetTypeDualStack, kops.SubnetTypePublic, kops.SubnetTypePrivate:
			bigSubnets = append(bigSubnets, subnet)

		case kops.SubnetTypeUtility:
			littleSubnets = append(littleSubnets, subnet)

		default:
			return fmt.Errorf("subnet %q has unknown type %q", subnet.Name, subnet.Type)
		}

		if subnet.CIDR != "" {

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Fix the subnet CIDR in the cluster spec to a valid CIDR (e.g. 10.0.0.0/24) using `kops edit cluster` or editing the manifest
  2. Validate with `kops validate cluster --name <cluster>` or `kops replace -f` to catch parse errors early
  3. If the CIDR should be auto-assigned, remove the cidr field from the subnet entirely and let assignCIDRsToSubnets allocate it

Example fix

// before
subnets:
- name: us-east-1a
  cidr: 10.0.1.0/33
// after
subnets:
- name: us-east-1a
  cidr: 10.0.1.0/24
Defensive patterns

Strategy: validation

Validate before calling

for _, s := range c.Spec.Networking.Subnets {
	if s.CIDR != "" {
		if _, _, err := net.ParseCIDR(s.CIDR); err != nil {
			return fmt.Errorf("subnet %q: bad CIDR %q: %w", s.Name, s.CIDR, err)
		}
	}
}

Type guard

func isValidCIDR(s string) bool {
	_, _, err := net.ParseCIDR(s)
	return s == "" || err == nil
}

Try / catch

if err := PerformAssignments(c, cloud); err != nil {
	var target *SubnetCIDRError
	if errors.As(err, &target) { /* fix manifest */ }
	return err
}

Prevention

When it happens

Trigger: Running `kops update cluster` (or other commands that call PerformAssignments) with cluster.spec.networking.subnets[i].cidr set to a malformed string, e.g. '10.0.0.0/33' or '10.0.0.0' (missing prefix length).

Common situations: Hand-edited cluster.yaml with a typo'd CIDR; copy-pasted IPv6 notation into an IPv4 field; forgetting the /prefix suffix; template placeholders like {{ cidr }} left unrendered.

Related errors


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