kubernetes/kops · error

unable to calculate subnet CIDR for

Error message

unable to calculate subnet CIDR for %q -> /%d#%d : %v

What it means

CIDRSubnet delegates the actual subnet computation to cidr.SubnetBig(baseCIDR, newSize-oldSize, netNum). If the requested new-bit expansion is invalid — e.g. newSize is smaller than or equal to the existing prefix size, or the expansion exceeds the address space — SubnetBig fails and the error is wrapped with the prefix, newSize, and netNum for diagnosis.

Solutions

  1. Ensure newSize is greater than the base prefix size and within the address space (e.g. /16 base, newSize 24 is valid; 16 is not).
  2. Keep netNum within [0, 2^(newSize-oldSize)); e.g. for an 8-bit expansion, netNum must be 0-255.
  3. Check calculateSubnetCIDR inputs (zone index, subnet count) for out-of-range arithmetic.
  4. Compute the expansion bits explicitly and assert 0 < newSize-oldSize <= totalSize-oldSize before calling.

Example fix

// before
subnet, err := utils.CIDRSubnet("172.20.0.0/16", 8, 1) // newSize smaller than oldSize
// after
subnet, err := utils.CIDRSubnet("172.20.0.0/16", 24, 1)
Defensive patterns

Strategy: validation

Validate before calling

func validSubnetRequest(prefix string, newSize int, netNum int64) error {
	_, cidrNet, err := net.ParseCIDR(prefix)
	if err != nil {
		return err
	}
	old, total := cidrNet.Mask.Size()
	if newSize <= old || newSize > total {
		return fmt.Errorf("newSize /%d must satisfy /%d < /%d <= /%d", newSize, old, newSize, total)
	}
	maxNet := int64(1) << uint(newSize-old)
	if netNum < 0 || netNum >= maxNet {
		return fmt.Errorf("netNum %d out of range [0,%d)", netNum, maxNet)
	}
	return nil
}

Prevention

When it happens

Trigger: Calling CIDRSubnet with newSize <= oldSize of the prefix (e.g. requesting /8 inside a /16), or newSize so large the subnet bits exceed the address family's total bits, or a netNum outside the range of addressable subnets (via calculateSubnetCIDR).

Common situations: Mistyped subnet-mask constants in cluster spec; asking for a subnet smaller than the parent prefix; offset/netnum exceeding the number of available subnets; IPv4 config values accidentally used in the IPv6 expansion path.

Related errors


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

Appendix: source

Thrown at upup/pkg/fi/utils/net.go:117

}

// CIDRSubnet calculates a subnet address within given IP network address prefix.
// Inspired by the Terraform implementation of the "cidrsubnet" function
// https://www.terraform.io/docs/language/functions/cidrsubnet.html
func CIDRSubnet(prefix string, newSize int, netNum int64) (string, error) {
	_, baseCIDR, err := net.ParseCIDR(prefix)
	if err != nil {
		return "", fmt.Errorf("unable to parse CIDR for %q: %v", prefix, err)
	}

	oldSize, totalSize := baseCIDR.Mask.Size()
	if oldSize == 0 && totalSize == 0 {
		return "", fmt.Errorf("unable to calculate CIDR mask size for %q: %q", prefix, baseCIDR.Mask)
	}

	newNetwork, err := cidr.SubnetBig(baseCIDR, newSize-oldSize, big.NewInt(netNum))
	if err != nil {
		return "", fmt.Errorf("unable to calculate subnet CIDR for %q -> /%d#%d : %v", prefix, newSize, netNum, err)
	}

	return newNetwork.String(), nil
}

View on GitHub (pinned to 4c8573c808)