kubernetes/kops · error

error Clusters cannot span multiple regions (found zone %q,

Error message

error Clusters cannot span multiple regions (found zone %q, but region is %q)

What it means

FindRegion infers the region from each subnet's zone (zone minus last character) and requires all zones to map to the same region, because a kops cluster cannot span multiple AWS regions. When a zone's derived region differs from the region already established by earlier subnets, this error is returned. (Note the literal message includes a leading 'error ' prefix from the format string.)

Source

Thrown at upup/pkg/fi/cloudup/awsup/aws_utils.go:110

func FindRegion(cluster *kops.Cluster) (string, error) {
	region := ""

	for _, subnet := range cluster.Spec.Networking.Subnets {
		if subnet.Zone == "" {
			// The zone of a subnet specified by ID is looked up from the cloud later.
			if subnet.ID == "" {
				return "", fmt.Errorf("subnet %q must specify a zone or the ID of an existing subnet", subnet.Name)
			}
			continue
		}

		if len(subnet.Zone) <= 2 {
			return "", fmt.Errorf("invalid AWS zone: %q in subnet %q", subnet.Zone, subnet.Name)
		}

		zoneRegion := subnet.Zone[:len(subnet.Zone)-1]
		if region != "" && zoneRegion != region {
			return "", fmt.Errorf("error Clusters cannot span multiple regions (found zone %q, but region is %q)", subnet.Zone, region)
		}

		region = zoneRegion
	}

	if region == "" {
		return "", fmt.Errorf("could not determine cluster region: no subnet specifies a zone")
	}

	return region, nil
}

// SupportsS3BootstrapEndpoint reports whether the region uses the amazonaws.com partition DNS
// suffix hard-coded by the nodeup bootstrap script. EC2 uses the same partition suffix as S3 and
// can be resolved without a bucket.
func SupportsS3BootstrapEndpoint(ctx context.Context, region string) (bool, error) {
	resolver := ec2.NewDefaultEndpointResolverV2()
	endpoint, err := resolver.ResolveEndpoint(ctx, ec2.EndpointParameters{Region: aws.String(region)})

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Make all subnet zones belong to a single region in the cluster spec
  2. Remove subnets from the other region, or create a separate cluster for that region
  3. Re-run `kops update cluster` after fixing the spec

Example fix

// before
subnets:
- name: a
  zone: us-east-1a
- name: b
  zone: eu-west-1a
// after
subnets:
- name: a
  zone: us-east-1a
- name: b
  zone: us-east-1b
Defensive patterns

Strategy: validation

Validate before calling

regions := map[string]bool{}
for _, s := range cluster.Spec.Networking.Subnets {
    if len(s.Zone) > 2 {
        regions[s.Zone[:len(s.Zone)-1]] = true
    }
}
if len(regions) > 1 { return fmt.Errorf("subnets span regions: %v", regions) }

Prevention

When it happens

Trigger: Iterating subnets in FindRegion where subnet.Zone[:len-1] differs from the region derived from a previous subnet — e.g. zones us-east-1a and eu-west-1a in the same cluster spec.

Common situations: Copy-pasting subnet entries across example cluster manifests from different regions; merging cluster specs during migration; accidentally including an old region's subnets when renaming a cluster.

Related errors


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