kubernetes/kops · error
Subnet %q has configured Zone %q, but the actual Zone found
Error message
Subnet %q has configured Zone %q, but the actual Zone found was %q
What it means
The cluster spec declares an availability zone for a subnet referenced by ID, but the actual AWS subnet resides in a different zone. Zone determines instance placement, so kOps refuses to silently override the spec with the cloud's zone.
Source
Thrown at upup/pkg/fi/cloudup/subnets.go:101
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)
}
}
}
if allSubnetsHaveCIDRs(c) {
klog.V(4).Infof("All subnets have CIDRs; skipping assignment logic")
return nilView on GitHub (pinned to 4c8573c808)
Solutions
- Check the subnet's actual AZ (`aws ec2 describe-subnets --subnet-ids subnet-xxxx --query 'Subnets[].AvailabilityZone'`) and set the spec's `zone` to match.
- Or remove the `zone` field so kOps derives it from the cloud (AWS subnets by ID).
- Or point the subnet at an ID in the zone you actually want.
Example fix
// before subnets: - id: subnet-0abc zone: us-east-1a # actual AZ: us-east-1b // after subnets: - id: subnet-0abc zone: us-east-1b
Defensive patterns
Strategy: validation
Validate before calling
actualAZ := describeSubnetAZ(subnetID, region)
if subnet.Zone != "" && subnet.Zone != actualAZ {
return fmt.Errorf("zone %s != cloud AZ %s for %s", subnet.Zone, actualAZ, subnetID)
} Prevention
- Let kOps derive the zone for ID-referenced AWS subnets instead of hardcoding it.
- Never reuse cluster specs across regions without regenerating subnet entries.
- Include AZ checks in pre-apply validation scripts.
When it happens
Trigger: Cluster spec sets `zone: us-east-1a` on a subnet whose ID is actually in us-east-1b (or vice versa), typically after copying subnet entries between clusters or reusing IDs from another region's plan.
Common situations: Spec generated for one region reused in another; subnet IDs swapped in a template; hand-edits of zones to work around capacity issues without changing the subnet ID.
Related errors
- subnet %q had unknown type %q
- Subnet %q has configured CIDR %q, but the actual CIDR found
- could not determine the zone of subnet %q; specify the zone
- 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/1c5008ff79dea33a.
Report an issue: GitHub.