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
- Make all subnet zones belong to a single region in the cluster spec
- Remove subnets from the other region, or create a separate cluster for that region
- 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
- Keep all subnets within one region; split cross-region needs into separate clusters
- When copying example manifests, adjust all zones to your region
- Add a CI check that derives one region from all zones
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
- invalid AWS zone: %q in subnet %q
- could not determine cluster region: no subnet specifies a zo
- getting AWS STS url: %w
- unhandled LoadBalancer type %q
- subnet %q had unknown type %q
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/fa4f134710813eb1.
Report an issue: GitHub.