{"record":{"id":"82f3eb67ae5321c9","repo":"kubernetes/kops","slug":"cannot-determine-control-plane-zones","errorCode":null,"errorMessage":"cannot determine control-plane zones","messagePattern":"cannot determine control-plane zones","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/cloudup/new_cluster.go","lineNumber":1003,"sourceCode":"\t\t\t}\n\n\t\t\tif controlPlaneCount == 0 {\n\t\t\t\t// If control-plane count is not specified, default to the number of control-plane zones\n\t\t\t\tcontrolPlaneCount = int32(len(controlPlaneZones))\n\t\t\t}\n\t\t} else {\n\t\t\t// controlPlaneZones not set; default to same as node Zones\n\t\t\tcontrolPlaneZones = opt.Zones\n\n\t\t\tif controlPlaneCount == 0 {\n\t\t\t\t// If control-plane count is not specified, default to 1\n\t\t\t\tcontrolPlaneCount = 1\n\t\t\t}\n\t\t}\n\n\t\tif len(controlPlaneZones) == 0 {\n\t\t\t// Should be unreachable\n\t\t\treturn nil, fmt.Errorf(\"cannot determine control-plane zones\")\n\t\t}\n\n\t\tfor i := 0; i < int(controlPlaneCount); i++ {\n\t\t\tzone := controlPlaneZones[i%len(controlPlaneZones)]\n\t\t\tname := zone\n\t\t\tif cloudProvider == api.CloudProviderDO {\n\t\t\t\tif int(controlPlaneCount) >= len(controlPlaneZones) {\n\t\t\t\t\tname += \"-\" + strconv.Itoa(1+(i/len(controlPlaneZones)))\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif int(controlPlaneCount) > len(controlPlaneZones) {\n\t\t\t\t\tname += \"-\" + strconv.Itoa(1+(i/len(controlPlaneZones)))\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tg := &api.InstanceGroup{}\n\t\t\tg.Spec.Role = api.InstanceGroupRoleControlPlane\n\t\t\tg.Spec.MinSize = new(int32(1))","sourceCodeStart":985,"sourceCodeEnd":1021,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/cloudup/new_cluster.go#L985-L1021","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Pass an explicit --zones flag with at least one zone (and --control-plane-zones if you want a distinct control-plane set).","Check that zone discovery works for your cloud/region (credentials, region setting) so kops can fill defaults.","If calling the API from Go, ensure NewClusterOptions.Zones or ControlPlaneZones is non-empty before NewCluster."],"exampleFix":"// before\nkops create cluster my.cluster --control-plane-count 3   # no zones\n// after\nkops create cluster my.cluster --zones us-east-1a,us-east-1b,us-east-1c --control-plane-count 3","handlingStrategy":"validation","validationCode":"[ -n \"$ZONES\" ] || [ -n \"$CP_ZONES\" ] || { echo \"provide --zones or --control-plane-zones\"; exit 1; }","typeGuard":null,"tryCatchPattern":"if err := createCluster(); err != nil && strings.Contains(err.Error(), \"cannot determine control-plane zones\") { /* supply --zones explicitly and retry */ }","preventionTips":["Always pass --zones explicitly in automation","Confirm zone discovery works for your cloud/region","Quote shell variables so --zones never expands empty"],"tags":["zones","control-plane","cluster-creation","configuration"],"backgroundTag":"missing-zones-configuration","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T07:17:12.445Z"}