{"record":{"id":"8eb75a205f0677e6","repo":"kubernetes/kops","slug":"cannot-parse-kubernetes-version-q","errorCode":null,"errorMessage":"cannot parse kubernetes version %q","messagePattern":"cannot parse kubernetes version %q","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"channels/pkg/cmd/apply_channel.go","lineNumber":195,"sourceCode":"\n\tdynamicClient, err := f.DynamicClient()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"building dynamic client: %w\", err)\n\t}\n\n\trestMapper, err := f.RESTMapper()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tkubernetesVersionInfo, err := k8sClient.Discovery().ServerVersion()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error querying kubernetes version: %v\", err)\n\t}\n\n\tkubernetesVersion, err := semver.ParseTolerant(kubernetesVersionInfo.GitVersion)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"cannot parse kubernetes version %q\", kubernetesVersionInfo.GitVersion)\n\t}\n\n\t// Remove Pre and Patch, as they make semver comparisons impractical\n\tkubernetesVersion.Pre = nil\n\n\tif len(args) == 0 {\n\t\treturn fmt.Errorf(\"at least one channel URL is required\")\n\t}\n\n\tvar merr error\n\tfor _, channelLocation := range args {\n\t\tmenu, err := buildMenu(f.VFSContext(), kubernetesVersion, channelLocation)\n\t\tif err != nil {\n\t\t\tmerr = multierr.Append(merr, fmt.Errorf(\"building menu for %q: %w\", channelLocation, err))\n\t\t\tcontinue\n\t\t}\n\t\tif err := applyMenu(ctx, menu, f.VFSContext(), k8sClient, cmClient, dynamicClient, restMapper, options.Yes); err != nil {\n\t\t\tmerr = multierr.Append(merr, fmt.Errorf(\"applying %q: %w\", channelLocation, err))","sourceCodeStart":177,"sourceCodeEnd":213,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/channels/pkg/cmd/apply_channel.go#L177-L213","documentation":"After fetching the server version, RunApplyChannel parses GitVersion with semver.ParseTolerant. If the reported version string cannot be parsed even tolerantly (no recognizable MAJOR.MINOR.PATCH anywhere), it fails with this message including the raw version string. This guards downstream feature-gating comparisons against unparsable versions.","triggerScenarios":"The apiserver's GitVersion is not a standard semver string: custom/rebuilt kube-apiserver binaries reporting e.g. 'dev' or a vendor string without digits, a proxy returning an HTML error page as version info, or a badly patched apiserver.","commonSituations":"Clusters fronted by a misconfigured load balancer/proxy that answers version requests itself; forked or locally-built Kubernetes reporting non-standard versions; mocks/stubs in testing environments.","solutions":["Inspect the actual version: `kubectl version -o json` and check GitVersion","Fix or bypass the proxy/LB answering the /version request instead of the apiserver","Use a standard Kubernetes build so GitVersion is proper semver","If unavoidable, patch the version string at the source (apiserver build) — kops expects semver-compatible GitVersion"],"exampleFix":"// before (custom build)\nGitVersion: \"my-fork\"\n// after\nGitVersion: \"v1.28.3\"","handlingStrategy":"validation","validationCode":"// Go: check the version string looks parseable before invoking\nv, _ := clientset.Discovery().ServerVersion()\nif !regexp.MustCompile(`\\d+\\.\\d+(\\.\\d+)?`).MatchString(v.GitVersion) {\n\treturn fmt.Errorf(\"non-semver GitVersion %q; fix cluster/proxy\", v.GitVersion)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Ensure nothing (LB/proxy) intercepts the /version endpoint","Use standard Kubernetes builds reporting semver GitVersion","Pin known cluster versions in CI to catch forks with odd version strings","Compare `kubectl version -o json` output against expectations"],"tags":["kubernetes","semver","version-parsing","discovery"],"backgroundTag":"unparsable-version-string","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"}