kubernetes/kops · error

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

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.

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)

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.