kubernetes/kops · error
failed to parse kubernetes version (%s): %w
Error message
failed to parse kubernetes version (%s): %w
What it means
ParseKubernetesVersion wraps any failure converting the numeric minor captured from a version-URL-like string (e.g. .../v1.23/) into a semver.Version. It fires when semver.ParseTolerant fails but the string matches versionURLPattern, and the extracted minor component is not a valid integer. The error preserves the original input and the underlying strconv error via %w.
Source
Thrown at pkg/apis/kops/util/versions.go:36
import (
"fmt"
"regexp"
"strconv"
"github.com/blang/semver/v4"
"k8s.io/klog/v2"
)
var versionURLPattern = regexp.MustCompile(`/v1\.([\d]+)\.`)
func ParseKubernetesVersion(version string) (*semver.Version, error) {
sv, err := semver.ParseTolerant(version)
if err != nil {
if submatch := versionURLPattern.FindStringSubmatch(version); len(submatch) >= 2 {
minor, err := strconv.Atoi(submatch[1])
if err != nil {
return nil, fmt.Errorf("failed to parse kubernetes version (%s): %w", version, err)
}
sv = semver.Version{Major: 1, Minor: uint64(minor)}
} else {
klog.Errorf("unable to parse Kubernetes version %q", version)
return nil, fmt.Errorf("unable to parse kubernetes version %q", version)
}
klog.V(1).Infof("Kubernetes version %q string matched to %v", version, sv)
}
return &sv, nil
}
// Deprecated: prefer using KubernetesVersion.IsGTE()
func IsKubernetesGTE(version string, k8sVersion semver.Version) bool {
parsedVersion, err := ParseKubernetesVersion(version)
if err != nil {
panic(fmt.Sprintf("Error parsing version %s: %v", version, err))
}View on GitHub (pinned to 4c8573c808)
Solutions
- Set the kubernetesVersion in the cluster spec to a plain semantic version like 1.28.4
- Verify the string actually matches the expected version-URL format (numeric minor) before parsing
- Use ParseKubernetesVersionInline/NormaliseKubernetesVersion or strip URL prefixes manually first
- Log and inspect the offending version value; fix the upstream config source producing it
Example fix
// before
v, err := ParseKubernetesVersion("https://storage.googleapis.com/k8s/release/vX.23")
// after
v, err := ParseKubernetesVersion("1.23.0") Defensive patterns
Strategy: validation
Validate before calling
re, _ := regexp.Compile(`/v1\.[0-9]+/?$`)
sv, err := semver.ParseTolerant(version)
if err != nil && !re.MatchString(version) {
return fmt.Errorf("invalid kubernetes version %q", version)
}
_, err = util.ParseKubernetesVersion(version)
if err != nil { /* abort before calling kops APIs */ } Type guard
func isParseableKubernetesVersion(v string) bool {
_, err := util.ParseKubernetesVersion(v)
return err == nil
} Try / catch
sv, err := util.ParseKubernetesVersion(raw)
if err != nil {
klog.Warningf("skipping unparseable kubernetes version %q: %v", raw, err)
return nil
} Prevention
- Always store plain semver strings (e.g. 1.28.4) in kubernetesVersion fields
- Validate version strings at config-load time, before calling kops APIs
- Avoid copying container image tags or URLs into version fields
- Add a CI check that parses all configured versions with ParseKubernetesVersion
When it happens
Trigger: Calling ParseKubernetesVersion (directly or via IsKubernetesGTE, IsGTE, RecommendedKubernetesVersion, FindRecommendedUpgrade, IsUpgradeRequired) with a string that fails strict/tolerant semver parsing but matches the version URL regex, where the regex's minor group is non-numeric (e.g. 'vX.abc' style URL).
Common situations: KubernetesVersion configured to a URL or image tag fragment instead of a plain version; cluster spec values copied from container image names; automated tooling substituting placeholders into the version field.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- unable to parse kubernetes version %q
- cannot parse kubernetes version %q
- error parsing version %q for package %q
- error parsing version %q: %v
- error parsing version %q: %w
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/f4a9d2635a1cc53f.
Report an issue: GitHub.