kubernetes/kops · critical

failed to parse network CIDR %q: %w

Error message

failed to parse network CIDR %q: %w

What it means

During nodeup config generation, kOps matches each API server address against the cluster's network CIDRs to pick control-plane IPs that nodes can reach. Before matching, every CIDR string (AdditionalNetworkCIDRs plus NetworkCIDR) is parsed with netip.ParsePrefix. This error is thrown when one of those CIDR strings is not a valid CIDR prefix, and the underlying netip parse error is wrapped in.

Source

Thrown at pkg/nodemodel/nodeupconfigbuilder.go:394

	config.Packages = append(config.Packages, cluster.Spec.Packages...)
	config.Packages = append(config.Packages, ig.Spec.Packages...)

	return config, bootConfig, nil
}

// selectControlPlaneIPs narrows the addresses that reach the API server down to the ones a node
// in this cluster can actually connect to. Some of the addresses may be FQDNs or public IPs.
func selectControlPlaneIPs(cluster *kops.Cluster, apiserverAddresses []string) ([]string, error) {
	var controlPlaneIPs []string

	switch cluster.GetCloudProvider() {
	case kops.CloudProviderAWS, kops.CloudProviderHetzner, kops.CloudProviderOpenstack:
		// Use a private IP address that belongs to the cluster network CIDR, or any IPv6 addresses (some additional addresses may be FQDNs or public IPs)
		for _, additionalIP := range apiserverAddresses {
			for _, networkCIDR := range append(cluster.Spec.Networking.AdditionalNetworkCIDRs, cluster.Spec.Networking.NetworkCIDR) {
				cidr, err := netip.ParsePrefix(networkCIDR)
				if err != nil {
					return nil, fmt.Errorf("failed to parse network CIDR %q: %w", networkCIDR, err)
				}
				ip, err := netip.ParseAddr(additionalIP)
				if err != nil {
					continue
				}
				// Nodes in an IPv6-only cluster sit in subnets that have no IPv4 CIDR, so an IPv4
				// address is unroutable from them even though it is inside the network CIDR. Handing
				// one out only stalls bootstrap on an address that can never answer.
				if cluster.Spec.IsIPv6Only() && !ip.Is6() {
					continue
				}
				if cidr.Contains(ip) || ip.Is6() {
					controlPlaneIPs = append(controlPlaneIPs, additionalIP)
				}
			}
		}

	case kops.CloudProviderGCE:

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Fix the offending CIDR in the cluster spec: `kops edit cluster` and set networkCIDR / additionalNetworkCIDRs to valid prefixes (e.g. 10.0.0.0/16, 2001:db8::/48), then `kops update cluster`.
  2. Check the wrapped netip error in the message: it names the exact bad string; validate it locally with `ipaddress.ip_network(...)` (python) or `netip.ParsePrefix` (Go) before re-running.
  3. Remove empty strings from additionalNetworkCIDRs (an empty list entry parses as an empty-string prefix and fails).
  4. Re-export the cluster spec from the API/Kubernetes state (`kops get cluster -o yaml`) to check for corruption between storage and what the builder sees.

Example fix

// before (cluster.yaml)
networking:
  networkCIDR: 10.0.0.0
// after
networking:
  networkCIDR: 10.0.0.0/16
Defensive patterns

Strategy: validation

Validate before calling

import "net/netip"

func validateNetworkCIDRs(networking kops.ClusterNetworkingSpec) error {
    for _, cidr := range append(networking.AdditionalNetworkCIDRs, networking.NetworkCIDR) {
        if _, err := netip.ParsePrefix(cidr); err != nil {
            return fmt.Errorf("invalid network CIDR %q: %w", cidr, err)
        }
    }
    return nil
}

Type guard

func isValidCIDR(s string) bool {
    _, err := netip.ParsePrefix(s)
    return s != "" && err == nil
}

Try / catch

ips, err := selectControlPlaneIPs(cluster, apiserverAddresses)
if err != nil {
    var perr *net.ParseError
    if errors.As(err, &perr) {
        // malformed CIDR in cluster spec: surface spec field + value
        return fmt.Errorf("cluster networking spec has invalid CIDR: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: Running `kops toolbox dump`, `kops get cluster -o yaml`-style config building, or any BuildConfig flow for an AWS/Hetzner/Openstack cluster where cluster.spec.networking.networkCIDR or additionalNetworkCIDRs contains a malformed value such as a bare IP (10.0.0.0 without /16), an empty string, or text like 'invalid'.

Common situations: Hand-edited cluster.spec.networking in the cluster manifest; IPv4 CIDR pasted into an IPv6-only cluster (or vice versa without a proper /128, /64); additionalNetworkCIDRs added by automation with trailing whitespace or a bare IP; upgrading from an old cluster spec where CIDR validation was looser.

Understand the failure class

Related errors


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