kubernetes/kops · error

cannot parse KubernetesVersion %q: %w

Error message

cannot parse KubernetesVersion %q: %w

What it means

NewCluster eagerly parses cluster.Spec.KubernetesVersion with util.ParseKubernetesVersion so invalid versions are caught before any cloud resources are created. The wrapped error (%w) carries the underlying parse failure.

Source

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

		ObjectMeta: v1.ObjectMeta{
			Name: opt.ClusterName,
		},
	}

	cluster.Spec.Channel = opt.Channel
	if opt.KubernetesVersion == "" {
		kubernetesVersion := api.RecommendedKubernetesVersion(channel, kops.Version)
		if kubernetesVersion != nil {
			cluster.Spec.KubernetesVersion = kubernetesVersion.String()
		}
	} else {
		cluster.Spec.KubernetesVersion = opt.KubernetesVersion
	}

	// Verify the kubernetes version early (while we can still handle the version nicely)
	if cluster.Spec.KubernetesVersion != "" {
		if _, err := util.ParseKubernetesVersion(cluster.Spec.KubernetesVersion); err != nil {
			return nil, fmt.Errorf("cannot parse KubernetesVersion %q: %w", cluster.Spec.KubernetesVersion, err)
		}
	}

	cluster.Spec.ConfigStore = api.ConfigStoreSpec{
		Base: opt.ConfigBase,
	}
	configBase, err := clientset.ConfigBaseFor(cluster)
	if err != nil {
		return nil, fmt.Errorf("error building ConfigBase for cluster: %v", err)
	}
	cluster.Spec.ConfigStore.Base = configBase.Path()

	cluster.Spec.Authorization = &api.AuthorizationSpec{}
	if strings.EqualFold(opt.Authorization, AuthorizationFlagAlwaysAllow) {
		cluster.Spec.Authorization.AlwaysAllow = &api.AlwaysAllowAuthorizationSpec{}
	} else if opt.Authorization == "" || strings.EqualFold(opt.Authorization, AuthorizationFlagRBAC) {
		cluster.Spec.Authorization.RBAC = &api.RBACAuthorizationSpec{}
	} else {

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Use a valid semver, e.g. `--kubernetes-version v1.29.4` (or 1.29.4 per parser expectations)
  2. Run `kops get instances` / check `kops version` supported versions and pick a listed release
  3. Omit the flag to use the default version recommended by the channel

Example fix

// before
opt.KubernetesVersion = "latest"
// after
opt.KubernetesVersion = "v1.29.4"
Defensive patterns

Strategy: validation

Validate before calling

if opt.KubernetesVersion != "" {
    if _, err := util.ParseKubernetesVersion(opt.KubernetesVersion); err != nil {
        return fmt.Errorf("invalid --kubernetes-version: %v", err)
    }
}

Try / catch

if _, err := NewCluster(opt, cs); err != nil {
    if strings.Contains(err.Error(), "cannot parse KubernetesVersion") {
        // prompt user for a valid semver
    }
}

Prevention

When it happens

Trigger: `kops create cluster --kubernetes-version <bad>` or NewClusterOptions.KubernetesVersion set to a string that is not a valid semver (e.g. "1", "v1.x", "latest", "1.29.3-beta.1+foo" variants the parser rejects).

Common situations: Typos in the version flag; using channel aliases like "latest" where a concrete version is required; copying versions from documentation that include a leading 'v' or extra qualifiers the strict parser rejects.

Related errors


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