kubernetes/kops · error

KubernetesVersion is required

Error message

KubernetesVersion is required

What it means

After normalization and defaulting, the target Kubernetes version must be known to build the full spec (component images, feature gates, etc.). run() throws this if spec.kubernetesVersion is still empty — FillDefaults does not always set it, e.g. when a channel/default cannot be derived.

Source

Thrown at upup/pkg/fi/cloudup/populate_cluster_spec.go:295

			klog.V(2).Infof("Defaulting DNS zone to: %s", dnsZone)
			cluster.Spec.DNSZone = dnsZone
		}
	}

	if !cluster.UsesNoneDNS() {
		if cluster.Spec.DNSZone != "" && cluster.Spec.API.PublicName == "" {
			cluster.Spec.API.PublicName = "api." + cluster.Name
		}
		if cluster.Spec.ExternalDNS == nil {
			cluster.Spec.ExternalDNS = &kopsapi.ExternalDNSConfig{}
		}
		if cluster.Spec.ExternalDNS.Provider == "" {
			cluster.Spec.ExternalDNS.Provider = kopsapi.ExternalDNSProviderDNSController
		}
	}

	if cluster.Spec.KubernetesVersion == "" {
		return fmt.Errorf("KubernetesVersion is required")
	}

	optionsContext, err := components.NewOptionsContext(cluster, c.assetBuilder, c.assetBuilder.KubeletSupportedVersion)
	if err != nil {
		return err
	}

	var codeModels []loader.ClusterOptionsBuilder
	{
		{
			// Note: DefaultOptionsBuilder comes first
			codeModels = append(codeModels, &components.DefaultsOptionsBuilder{Context: optionsContext})
			codeModels = append(codeModels, &components.EtcdOptionsBuilder{OptionsContext: optionsContext})
			codeModels = append(codeModels, &etcdmanager.EtcdManagerOptionsBuilder{OptionsContext: optionsContext})
			codeModels = append(codeModels, &components.KubeAPIServerOptionsBuilder{OptionsContext: optionsContext})
			codeModels = append(codeModels, &components.ContainerdOptionsBuilder{OptionsContext: optionsContext})
			codeModels = append(codeModels, &components.NetworkingOptionsBuilder{Context: optionsContext})
			codeModels = append(codeModels, &components.KubeDnsOptionsBuilder{Context: optionsContext})

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Set spec.kubernetesVersion in the cluster spec (e.g. "1.28.4") or pass --kubernetes-version on create.
  2. Ensure a valid channel is configured so defaults can supply the version if you rely on automatic defaults.
  3. Use `kops create cluster ... --kubernetes-version <version>` instead of hand-built manifests lacking the field.

Example fix

# before
metadata:
  name: cluster.example.com
spec:
  # kubernetesVersion missing
# after
metadata:
  name: cluster.example.com
spec:
  kubernetesVersion: 1.28.4
Defensive patterns

Strategy: validation

Validate before calling

if cluster.Spec.KubernetesVersion == "" {
	return fmt.Errorf("kubernetesVersion must be set (or pass --kubernetes-version)")
}

Type guard

func hasKubernetesVersion(c *kopsapi.Cluster) bool { return strings.TrimSpace(c.Spec.KubernetesVersion) != "" }

Prevention

When it happens

Trigger: Calling PopulateClusterSpec on a cluster spec with kubernetesVersion unset, typically when creating a cluster without --kubernetes-version and no default channel resolution applied, or a hand-written spec omitting the field.

Common situations: `kops create cluster` from a custom YAML missing kubernetesVersion; base cluster specs generated by tooling that omits the field; pinned-channel configs where the channel no longer supplies a default.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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