kubernetes/kops · error

error parsing CIDR

Error message

error parsing CIDR %q: %v

What it means

CIDRMap.Allocate carves subnets out of a parent range given as a CIDR string. The `from` argument must parse via net.ParseCIDR; if it doesn't, allocation cannot start and this error quotes the invalid range. Like MarkInUse it validates the same input class but under the Allocate entry point.

Solutions

  1. Correct the base CIDR string to valid notation (e.g. 10.0.0.0/16) and retry
  2. Validate the value before calling Allocate (net.ParseCIDR in a pre-check)
  3. Fix the cluster spec field supplying this value (kops edit cluster) and update the cluster

Example fix

// before
subnet, err := cidrMap.Allocate("10.0.0.0/33", mask)
// after
subnet, err := cidrMap.Allocate("10.0.0.0/16", mask)
Defensive patterns

Strategy: validation

Validate before calling

if _, _, err := net.ParseCIDR(from); err != nil {
	return nil, fmt.Errorf("base CIDR %q invalid: %w", from, err)
}

Type guard

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

Prevention

When it happens

Trigger: Calling Allocate with a malformed `from` base CIDR — e.g. "10.0.0.0" without /mask, an out-of-range prefix like /33, or IPv6 text where IPv4 is expected — typically from subnet/cidr allocation during cluster creation.

Common situations: Cluster spec with a bad nonMasqueradeCIDR or subnet base range, typo'd YAML values, or programmatically built CIDR strings that were never validated.

Related errors


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

Appendix: source

Thrown at pkg/util/subnet/cidrmap.go:84

				newHigh++
			}
		}
		binary.BigEndian.PutUint64(ip[0:8], newHigh)
		binary.BigEndian.PutUint64(ip[8:16], newLow)
	}
	return nil
}

func duplicateIP(src net.IP) net.IP {
	ret := make(net.IP, len(src))
	copy(ret, src)
	return ret
}

func (c *CIDRMap) Allocate(from string, mask net.IPMask) (*net.IPNet, error) {
	_, cidr, err := net.ParseCIDR(from)
	if err != nil {
		return nil, fmt.Errorf("error parsing CIDR %q: %v", from, err)
	}

	var candidate net.IPNet
	candidate.Mask = mask
	candidate.IP = duplicateIP(cidr.IP)

	for {
		// Note we increment first, so we won't ever use the first range (e.g. 10.0.0.0/n)
		if err := incrementIP(candidate.IP, mask); err != nil {
			return nil, err
		}

		// Check we're still in the range we're drawing from
		if !cidrsOverlap(cidr, &candidate) {
			klog.Infof("candidate CIDR %v is not in CIDR %v", candidate, cidr)
			break
		}

View on GitHub (pinned to 4c8573c808)