kubernetes/kops · error

unable to determine zones in region %q

Error message

unable to determine zones in region %q

What it means

After listing zones, ListResourcesGCE filters zones whose region matches the cluster's region and collects their names into d.zones; if no zone matched, it fails with 'unable to determine zones in region %q'. This indicates the region configured for the cluster has no listed zones, i.e. the region name is wrong or the project can't see that region.

Source

Thrown at pkg/resources/gce/gce.go:93

	{
		// TODO: Only zones in api.Cluster object, if we have one?
		gceZones, err := d.gceCloud.Compute().Zones().List(ctx, d.gceCloud.Project())
		if err != nil {
			return nil, fmt.Errorf("error listing zones: %v", err)
		}
		for _, gceZone := range gceZones {
			u, err := gce.ParseGoogleCloudURL(gceZone.Region)
			if err != nil {
				return nil, err
			}
			if u.Name != region {
				continue
			}
			d.zones = append(d.zones, gceZone.Name)
		}
		if len(d.zones) == 0 {
			return nil, fmt.Errorf("unable to determine zones in region %q", region)
		}
		klog.Infof("Scanning zones: %v", d.zones)
	}

	listFunctions := []gceListFn{
		d.listGCEInstanceTemplates,
		d.listInstanceGroupManagersAndInstances,
		d.listTargetPools,
		d.listForwardingRules,
		d.listFirewallRules,
		d.listGCEDisks,
		d.listAddresses,
		d.listSubnets,
		d.listRouters,
		d.listNetworks,
		d.listServiceAccounts,
		d.listBackendServices,
		d.listHealthchecks,

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Verify the region with 'gcloud compute zones list --project <project>' and make sure the cluster's region exactly matches (e.g. 'us-east1', not a zone like 'us-east1-b').
  2. Correct the region in the kops cluster spec and re-run the command.
  3. If the region is valid but zones are missing, check GCP region availability for the project or contact GCP support.
  4. Add debug logging (klog) of each gceZone.Region vs the target region to spot normalization mismatches.

Example fix

// before
if len(d.zones) == 0 {
	return nil, fmt.Errorf("unable to determine zones in region %q", region)
}
// after
if len(d.zones) == 0 {
	return nil, fmt.Errorf("unable to determine zones in region %q (project %q)", region, d.gceCloud.Project())
}
Defensive patterns

Strategy: validation

Validate before calling

// validate region against the live project before listing resources
zones, err := computeService.Zones.List(project).Do()
if err != nil { return err }
valid := map[string]bool{}
for _, z := range zones.Items {
	region := z.Region[strings.LastIndex(z.Region, "/")+1:]
	valid[region] = true
}
if !valid[targetRegion] {
	return fmt.Errorf("region %q has no zones in project %q; valid: %v", targetRegion, project, valid)
}

Type guard

var gceRegionRe = regexp.MustCompile(`^[a-z]+-[a-z]+[0-9]$`)
func isWellFormedGCPRegion(r string) bool { return gceRegionRe.MatchString(r) }

Try / catch

if err := ListResourcesGCE(ctx, d, cluster, op); err != nil {
	if strings.Contains(err.Error(), "unable to determine zones in region") {
		// surface valid regions to the user instead of a bare failure
		return fmt.Errorf("%v — check the cluster spec's region (must be like 'us-east1', not a zone name)", err)
	}
	return err
}

Prevention

When it happens

Trigger: The resolved region string doesn't match any gceZone.Region returned by the API — typically a misspelled region (e.g. 'us-east1' vs 'us-east1-b' or 'us-central'), a region not available to the project, or ParseGoogleCloudURL producing an unexpected u.Name.

Common situations: Typo in the cluster spec's region, running against a project where the chosen region is disabled/not yet available, or GCP added/removed zones leaving an edge case where region exists but filtering logic mismatches.

Related errors


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