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 nil

View on GitHub (pinned to 4c8573c808)

Solutions

  1. 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.
  2. Or remove the `zone` field so kOps derives it from the cloud (AWS subnets by ID).
  3. 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

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


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