kubernetes/kops · error

invalid GCE Zone: %v

Error message

invalid GCE Zone: %v

What it means

ZoneToRegion maps a GCE zone (e.g. us-central1-a) to its region (us-central1) by splitting on '-' and keeping the first two tokens. The guard requires MORE than 2 tokens (len(tokens) <= 2 errors), so valid zones like "us-central1-a" (3 tokens) pass, but any string with two or fewer dash-separated parts — including a region passed by mistake — is rejected.

Source

Thrown at upup/pkg/fi/cloudup/gce/utils.go:172

// instance's "ssh-keys" metadata; the GCE guest agent creates this user on first boot. kOps
// historically used fi.SecretNameSSHPrimary ("admin"), but on Ubuntu images the guest agent fails
// to create that user because those images ship with an "admin" group
// (https://github.com/kubernetes/kops/issues/16175), so the key was never installed. For Ubuntu
// images we use the image's built-in "ubuntu" user instead. Other images keep "admin" so that SSH
// access to existing non-Ubuntu clusters is unchanged.
func SSHUsernameForImage(image string) string {
	name := LastComponent(image)
	if strings.HasPrefix(strings.ToLower(name), "ubuntu") {
		return "ubuntu"
	}
	return fi.SecretNameSSHPrimary
}

// ZoneToRegion maps a GCE zone name to a GCE region name, returning an error if it cannot be mapped
func ZoneToRegion(zone string) (string, error) {
	tokens := strings.Split(zone, "-")
	if len(tokens) <= 2 {
		return "", fmt.Errorf("invalid GCE Zone: %v", zone)
	}
	region := tokens[0] + "-" + tokens[1]
	return region, nil
}

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Pass a full zone with the -x suffix, e.g. "us-central1-a" not "us-central1"
  2. Fix the config/flag/env that produced the empty or malformed zone value
  3. Trim whitespace and validate the zone format before calling
  4. Use `gcloud compute zones list` to confirm the exact zone name

Example fix

// before
region, err := ZoneToRegion("us-central1") // invalid GCE Zone: us-central1
// after
region, err := ZoneToRegion("us-central1-a") // "us-central1", nil
Defensive patterns

Strategy: validation

Validate before calling

func validateGCEZone(zone string) error {
    tokens := strings.Split(zone, "-")
    if len(tokens) <= 2 {
        return fmt.Errorf("invalid GCE Zone %q: expected format like us-central1-a", zone)
    }
    return nil
}
// call validateGCEZone(cfg.Zone) before ZoneToRegion

Try / catch

region, err := ZoneToRegion(zone)
if err != nil {
    return fmt.Errorf("config.zone must be a full zone (e.g. us-central1-a), got %q: %w", zone, err)
}

Prevention

When it happens

Trigger: Calling ZoneToRegion with an empty string, a bare region like "us-central1", or any malformed zone lacking a final dash component.

Common situations: Config supplying a region where a zone is expected; empty zone from unset environment/flags; truncated zone strings from parsing mistakes; typos like "uscentral1a".

Related errors


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