kubernetes/kops · error

cannot determine control-plane zones

Error message

cannot determine control-plane zones

What it means

setupControlPlane could not determine any availability zone for control-plane nodes. The code marks this as "should be unreachable": control-plane zones default to the general --zones list, so if that list is empty and --control-plane-zones was not given, cluster construction cannot proceed and this defensive error is returned.

Source

Thrown at upup/pkg/fi/cloudup/new_cluster.go:1003

			}

			if controlPlaneCount == 0 {
				// If control-plane count is not specified, default to the number of control-plane zones
				controlPlaneCount = int32(len(controlPlaneZones))
			}
		} else {
			// controlPlaneZones not set; default to same as node Zones
			controlPlaneZones = opt.Zones

			if controlPlaneCount == 0 {
				// If control-plane count is not specified, default to 1
				controlPlaneCount = 1
			}
		}

		if len(controlPlaneZones) == 0 {
			// Should be unreachable
			return nil, fmt.Errorf("cannot determine control-plane zones")
		}

		for i := 0; i < int(controlPlaneCount); i++ {
			zone := controlPlaneZones[i%len(controlPlaneZones)]
			name := zone
			if cloudProvider == api.CloudProviderDO {
				if int(controlPlaneCount) >= len(controlPlaneZones) {
					name += "-" + strconv.Itoa(1+(i/len(controlPlaneZones)))
				}
			} else {
				if int(controlPlaneCount) > len(controlPlaneZones) {
					name += "-" + strconv.Itoa(1+(i/len(controlPlaneZones)))
				}
			}

			g := &api.InstanceGroup{}
			g.Spec.Role = api.InstanceGroupRoleControlPlane
			g.Spec.MinSize = new(int32(1))

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Pass an explicit --zones flag with at least one zone (and --control-plane-zones if you want a distinct control-plane set).
  2. Check that zone discovery works for your cloud/region (credentials, region setting) so kops can fill defaults.
  3. If calling the API from Go, ensure NewClusterOptions.Zones or ControlPlaneZones is non-empty before NewCluster.

Example fix

// before
kops create cluster my.cluster --control-plane-count 3   # no zones
// after
kops create cluster my.cluster --zones us-east-1a,us-east-1b,us-east-1c --control-plane-count 3
Defensive patterns

Strategy: validation

Validate before calling

[ -n "$ZONES" ] || [ -n "$CP_ZONES" ] || { echo "provide --zones or --control-plane-zones"; exit 1; }

Try / catch

if err := createCluster(); err != nil && strings.Contains(err.Error(), "cannot determine control-plane zones") { /* supply --zones explicitly and retry */ }

Prevention

When it happens

Trigger: Calling NewCluster (via `kops create cluster`) with neither --zones nor --control-plane-zones resolvable to a non-empty list, e.g. omitting --zones while cloud zones lookup yields nothing, or programmatic use of NewClusterOptions with empty Zones and ControlPlaneZones.

Common situations: Scripted cluster creation where --zones was dropped or is empty due to a variable expansion failure; using a cloud/region combination where zone discovery returns no zones; constructing NewClusterOptions in Go tests without setting Zones.

Related errors


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