kubernetes/kops · error
unable to determine kubernetes version from %q
Error message
unable to determine kubernetes version from %q
What it means
NewOptionsContext parses cluster.spec.kubernetesVersion with util.ParseKubernetesVersion to populate the options context. An empty or unparseable version string (not semver-ish, junk text) makes it impossible to compute component defaults, so construction fails with this error.
Source
Thrown at pkg/model/components/context.go:58
// Deprecated: Prefer using NodeKubernetesVersion() and ControlPlaneKubernetesVersion()
KubernetesVersion semver.Version
AssetBuilder *assets.AssetBuilder
nodeKubernetesVersion kopsmodel.KubernetesVersion
controlPlaneKubernetesVersion kopsmodel.KubernetesVersion
}
func NewOptionsContext(cluster *kops.Cluster, assetBuilder *assets.AssetBuilder, maxKubeletSupportedVersion string) (*OptionsContext, error) {
optionsContext := &OptionsContext{
ClusterName: cluster.ObjectMeta.Name,
AssetBuilder: assetBuilder,
}
sv, err := util.ParseKubernetesVersion(cluster.Spec.KubernetesVersion)
if err != nil {
return nil, fmt.Errorf("unable to determine kubernetes version from %q", cluster.Spec.KubernetesVersion)
}
optionsContext.KubernetesVersion = *sv
controlPlaneKubernetesVersion, err := kopsmodel.ParseKubernetesVersion(cluster.Spec.KubernetesVersion)
if err != nil {
return nil, fmt.Errorf("unable to determine kubernetes version from %q: %w", cluster.Spec.KubernetesVersion, err)
}
nodeKubernetesVersion := controlPlaneKubernetesVersion
if maxKubeletSupportedVersion != "" {
nodeKubernetesVersion, err = kopsmodel.ParseKubernetesVersion(maxKubeletSupportedVersion)
if err != nil {
return nil, fmt.Errorf("unable to determine kubernetes version from %q: %w", maxKubeletSupportedVersion, err)
}
}
optionsContext.nodeKubernetesVersion = *nodeKubernetesVersion
optionsContext.controlPlaneKubernetesVersion = *controlPlaneKubernetesVersion
View on GitHub (pinned to 4c8573c808)
Solutions
- Set an explicit valid version, e.g. `kops create cluster --kubernetes-version v1.30.4 ...`
- If you intended the default, omit the field entirely so kops picks its default version
- Check the CI variable substitution — ensure KUBERNETES_VERSION is not empty
Example fix
# before (empty via unset var) kops create cluster ... --kubernetes-version "$VER" # after export VER=v1.30.4 kops create cluster ... --kubernetes-version "$VER"
Defensive patterns
Strategy: validation
Validate before calling
if _, err := util.ParseKubernetesVersion(cluster.Spec.KubernetesVersion); err != nil {
return fmt.Errorf("--kubernetes-version must be valid semver, got %q", cluster.Spec.KubernetesVersion)
} Type guard
func validKubernetesVersion(v string) bool {
_, err := util.ParseKubernetesVersion(v)
return err == nil
} Try / catch
if err := createCluster(); err != nil {
if strings.Contains(err.Error(), "unable to determine kubernetes version") {
// fall back to `kops get instancegroup`-style default version
}
return err
} Prevention
- Always pass --kubernetes-version vMAJOR.MINOR.PATCH to create cluster
- Quote and default CI variables: VER="${VER:-v1.30.4}"
- Never use 'latest'/'stable' as a version in manifests
When it happens
Trigger: cluster.Spec.KubernetesVersion is empty, or set to a non-parseable value (e.g. 'latest', 'v1', 'stable', or a plain git hash without semver metadata).
Common situations: Creating a cluster without --kubernetes-version; CI scripts substituting an unset variable (empty string); hand-edited manifests with arbitrary version strings.
Related errors
- cannot parse kubernetes version %q
- validation of the full cluster and instance group specs fail
- error populating configuration: %v
- error loading Cluster %q: %v
- error parsing Cluster %q: %v
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/363a5cabaf2334f7.
Report an issue: GitHub.