kubernetes/kops · error

instance was in zone %q, expected region %q

Error message

instance was in zone %q, expected region %q

What it means

After fetching the instance, the verifier requires its zone to fall inside its configured region (zone name must start with v.opt.Region + "-"). This keeps the trusted node pool scoped to the cluster's region and rejects instances from elsewhere.

Source

Thrown at upup/pkg/fi/cloudup/gce/tpm/gcetpmverifier/tpmverifier.go:138

	if tokenData.Instance == "" {
		return nil, fmt.Errorf("instance is required")
	}

	// Verify node is in our cluster
	if tokenData.GCPProjectID != v.opt.ProjectID {
		return nil, fmt.Errorf("projectID does not match expected: got %q, want %q", tokenData.GCPProjectID, v.opt.ProjectID)
	}

	instance, err := v.computeClient.Instances.Get(tokenData.GCPProjectID, tokenData.Zone, tokenData.Instance).Context(ctx).Do()
	if err != nil {
		if isNotFound(err) {
			return nil, fmt.Errorf("unable to find instance in compute API: %w", err)
		}
		return nil, fmt.Errorf("error fetching instance from compute API: %w", err)
	}

	if !strings.HasPrefix(lastComponent(instance.Zone), v.opt.Region+"-") {
		return nil, fmt.Errorf("instance was in zone %q, expected region %q", instance.Zone, v.opt.Region)
	}

	clusterName := ""
	instanceGroupName := ""
	for _, item := range instance.Metadata.Items {
		switch item.Key {
		case gce.MetadataKeyInstanceGroupName:
			instanceGroupName = fi.ValueOf(item.Value)
		case gcemetadata.MetadataKeyClusterName:
			clusterName = fi.ValueOf(item.Value)
		}
	}

	capgRole := instance.Labels[gce.LabelKeyCAPIRoleName]

	if clusterName == "" {
		return nil, fmt.Errorf("could not determine cluster for instance %s", instance.SelfLink)
	}

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Update v.opt.Region in the verifier configuration to include the region the instance actually runs in.
  2. Move the node's instance group into the configured region, or deploy a verifier per region.
  3. Ensure the cluster's GCE provider settings (regions) and verifier options were updated together after any region migration.

Example fix

// before
v.opt.Region = "us-central1"
// after (nodes actually in us-west1)
v.opt.Region = "us-west1"
Defensive patterns

Strategy: validation

Validate before calling

if !strings.HasPrefix(lastComponent(instance.Zone), expectedRegion+"-") {
	return fmt.Errorf("instance zone %s outside expected region %s", instance.Zone, expectedRegion)
}

Prevention

When it happens

Trigger: lastComponent(instance.Zone) (e.g. "us-west1-b") does not begin with v.opt.Region + "-" (e.g. "us-central1").

Common situations: Nodes provisioned in a different region than the verifier's Region option, cluster expanded cross-region without updating the verifier, multi-region fleets hitting a single verifier, or a stale Region value after migrating the cluster.

Related errors


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