kubernetes/kops · error
Subnet %q did not have CIDR
Error message
Subnet %q did not have CIDR
What it means
kOps looked up an existing cloud subnet by ID to inherit its CIDR, but the subnet has no IPv4 CIDR. This is allowed only for IPv6-only private subnets (which have an IPv6CIDR and type Private); otherwise kOps cannot do its IPv4-based CIDR allocation and aborts.
Source
Thrown at upup/pkg/fi/cloudup/subnets.go:92
return fmt.Errorf("VPC %q not found", c.Spec.Networking.NetworkID)
}
subnetByID := make(map[string]*fi.SubnetInfo)
for _, subnetInfo := range vpcInfo.Subnets {
subnetByID[subnetInfo.ID] = subnetInfo
}
for i := range c.Spec.Networking.Subnets {
subnet := &c.Spec.Networking.Subnets[i]
if subnet.ID != "" {
cloudSubnet := subnetByID[subnet.ID]
if cloudSubnet == nil {
return fmt.Errorf("Subnet %q not found in VPC %q", subnet.ID, c.Spec.Networking.NetworkID)
}
if subnet.CIDR == "" {
subnet.CIDR = cloudSubnet.CIDR
// IPv6-only private subnets do not have an IPv4 CIDR
if subnet.CIDR == "" && (subnet.IPv6CIDR == "" || subnet.Type != kops.SubnetTypePrivate) {
return fmt.Errorf("Subnet %q did not have CIDR", subnet.ID)
}
} else if subnet.CIDR != cloudSubnet.CIDR {
return fmt.Errorf("Subnet %q has configured CIDR %q, but the actual CIDR found was %q", subnet.ID, subnet.CIDR, cloudSubnet.CIDR)
}
if needZones && subnet.Zone == "" {
subnet.Zone = cloudSubnet.Zone
} else if subnet.Zone != cloudSubnet.Zone {
return fmt.Errorf("Subnet %q has configured Zone %q, but the actual Zone found was %q", subnet.ID, subnet.Zone, cloudSubnet.Zone)
}
}
}
}
if needZones {
for i := range c.Spec.Networking.Subnets {
subnet := &c.Spec.Networking.Subnets[i]View on GitHub (pinned to 4c8573c808)
Solutions
- Set `type: Private` and provide `ipv6CIDR` for the IPv6-only subnet in the cluster spec.
- Alternatively use a subnet that has an IPv4 CIDR (dualstack), or specify an explicit `cidr` for the subnet.
- Re-run `kops update cluster` after editing the spec.
Example fix
// before subnets: - id: subnet-0abc type: Public // after subnets: - id: subnet-0abc type: Private ipv6CIDR: 2600:1f18:xxxx::/64
Defensive patterns
Strategy: validation
Validate before calling
// IPv6-only subnets must be Private and carry ipv6CIDR
if !hasIPv4CIDR(subnetID) && (subnet.Type != "Private" || subnet.IPv6CIDR == "") {
return fmt.Errorf("subnet %s is IPv6-only; set type=Private and ipv6CIDR", subnetID)
} Prevention
- Set type: Private plus ipv6CIDR for any IPv6-only subnet.
- Prefer dualstack subnets when IPv4 connectivity is required.
- Document subnet addressing in shared-VPC onboarding docs.
When it happens
Trigger: An AWS subnet referenced by ID that is IPv6-only (no IPv4 CIDR) but is declared in the cluster spec as a type other than Private, or declared without any IPv6CIDR.
Common situations: IPv6-only dualstack migrations where the subnet type in the spec was left as Public/Utility; users attaching an IPv6-only subnet from a shared VPC without setting subnet type Private.
Related errors
- IPv6 CIDR block provided by Amazon not found
- error associating Amazon IPv6 provided CIDR block to VPC: %v
- Subnet %q has configured CIDR %q, but the actual CIDR found
- unexpected number of network interfaces for instance %q: %v
- unexpected amount of ipv6 prefixes on interface %q: %v
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/92392a07e42d6fb9.
Report an issue: GitHub.