kubernetes/kops · error
Subnet %q has configured CIDR %q, but the actual CIDR found
Error message
Subnet %q has configured CIDR %q, but the actual CIDR found was %q
What it means
The cluster spec declares an explicit CIDR for a subnet referenced by ID, but the CIDR actually configured on that cloud subnet differs. kOps treats the cloud as the source of truth for existing subnets and refuses to proceed with a conflicting spec value.
Source
Thrown at upup/pkg/fi/cloudup/subnets.go:95
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]
if subnet.ID != "" && subnet.Zone == "" {
return fmt.Errorf("could not determine the zone of subnet %q; specify the zone in the cluster spec", subnet.Name)
}View on GitHub (pinned to 4c8573c808)
Solutions
- Read the real CIDR (`aws ec2 describe-subnets --subnet-ids subnet-xxxx`) and set the spec's `cidr` to match, or simply remove the `cidr` field so kOps adopts the cloud value.
- Re-run `kops update cluster`.
- If you intended a different CIDR, create/point to a subnet that actually has it.
Example fix
// before subnets: - id: subnet-0abc cidr: 10.0.1.0/24 # actual: 10.0.16.0/20 // after subnets: - id: subnet-0abc # cidr omitted; inherited from cloud
Defensive patterns
Strategy: validation
Validate before calling
actual := describeSubnetCIDR(subnetID, region)
if subnet.CIDR != "" && subnet.CIDR != actual {
return fmt.Errorf("cidr %s != cloud cidr %s for %s", subnet.CIDR, actual, subnetID)
} Prevention
- Omit the explicit `cidr` field for ID-referenced subnets and let kOps inherit it from the cloud.
- Re-generate cluster specs after any manual subnet CIDR change.
- Diff the spec against live cloud state in CI.
When it happens
Trigger: Cluster spec has both `id: subnet-xxxx` and `cidr: 10.0.1.0/24` where the real AWS subnet CIDR is something else — usually after the subnet was resized/changed out-of-band or the spec was written for a different subnet.
Common situations: Subnet CIDR changed by another team after the cluster spec was generated; copying a cluster.yaml between environments; typo in the configured CIDR.
Related errors
- subnet %q had unknown type %q
- Subnet %q did not have CIDR
- Subnet %q has configured Zone %q, but the actual Zone found
- subnet %q had unknown type %q
- unhandled bastion LoadBalancer type %q
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/1908db5d0d97dbf1.
Report an issue: GitHub.