{"record":{"id":"4aeb0e3529aa04f0","repo":"GoogleContainerTools/skaffold","slug":"couldn-t-get-kubectl-minor-version-w","errorCode":null,"errorMessage":"couldn't get kubectl minor version: %w","messagePattern":"couldn't get kubectl minor version: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/skaffold/kubectl/version.go","lineNumber":71,"sourceCode":"// CheckVersion warns the user if their kubectl version is < 1.12.0\nfunc (c *CLI) CheckVersion(ctx context.Context) error {\n\tcomp, err := c.CompareVersionTo(ctx, 1, 12)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif comp < 0 {\n\t\treturn errors.New(\"kubectl version 1.12.0 or greater is recommended for use with Skaffold\")\n\t}\n\treturn nil\n}\n\nfunc (c *CLI) CompareVersionTo(ctx context.Context, vMajor, vMinor int) (int, error) {\n\tv := c.Version(ctx)\n\n\tmajorInt, err := strconv.Atoi(v.Major)\n\tif err != nil {\n\t\treturn 0, fmt.Errorf(\"couldn't get kubectl minor version: %w\", err)\n\t}\n\n\t// Some patched versions get a '+' suffix.\n\tminorInt, err := strconv.Atoi(strings.TrimRight(v.Minor, \"+\"))\n\tif err != nil {\n\t\treturn 0, fmt.Errorf(\"couldn't get kubectl minor version: %w\", err)\n\t}\n\n\tif majorInt > vMajor {\n\t\treturn 1, nil\n\t}\n\tif majorInt == vMajor {\n\t\tif minorInt > vMinor {\n\t\t\treturn 1, nil\n\t\t}\n\t\tif minorInt == vMinor {\n\t\t\treturn 0, nil\n\t\t}","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/GoogleContainerTools/skaffold/blob/a1189de023efc32d4b8e11f395acc678aa555011/pkg/skaffold/kubectl/version.go#L53-L89","documentation":"CompareVersionTo runs `kubectl version` via c.Version(ctx) and parses Major/Minor with strconv.Atoi to compare against a required version. When the Major string is not a plain integer, the parse error is wrapped — note the message misleadingly says 'minor version' even for the Major failure (a copy-paste bug in the error text).","triggerScenarios":"kubectl's reported Major version string is non-numeric: empty output (kubectl missing/failing), error/usage text instead of version info, or forked kubectl builds emitting suffixed versions like \"1\" with annotations the parser doesn't expect.","commonSituations":"kubectl not on PATH or failing to execute so Version returns empty fields; vendor/patched kubectl (GKE, Rancher, OpenShift forks) printing non-standard version strings; stale PATH entry pointing at a broken kubectl.","solutions":["Run `kubectl version --client` and confirm it prints numeric major/minor values","Install a standard upstream kubectl matching your cluster and put it first on PATH","If using a forked kubectl whose version has suffixes, switch to upstream or update Skaffold"],"exampleFix":"// before: forked kubectl prints Major=\"v1\" -> Atoi fails\n// after: install upstream kubectl so Version() returns Major=\"1\", Minor=\"27\"\nkubectl version --client=true -o json | jq -r '.clientVersion.major'","handlingStrategy":"validation","validationCode":"out, err := exec.Command(\"kubectl\", \"version\", \"--client\", \"-o\", \"json\").Output()\nif err != nil {\n    return fmt.Errorf(\"kubectl unavailable: %w\", err)\n}\nvar v struct{ ClientVersion struct{ Major, Minor string } }\nif json.Unmarshal(out, &v) != nil || v.ClientVersion.Major == \"\" {\n    return errors.New(\"kubectl returned non-standard version output; install upstream kubectl\")\n}","typeGuard":"func validKubectlVersion(major, minor string) bool {\n    _, err1 := strconv.Atoi(major)\n    _, err2 := strconv.Atoi(strings.TrimRight(minor, \"+\"))\n    return err1 == nil && err2 == nil\n}","tryCatchPattern":"cmp, err := cli.CompareVersionTo(ctx, 1, 20)\nif err != nil {\n    var perr *strconv.NumError\n    if errors.As(err, &perr) {\n        return fmt.Errorf(\"kubectl version output unparseable (%s); reinstall upstream kubectl: %w\", perr.Num, err)\n    }\n    return err\n}","preventionTips":["Install standard upstream kubectl (not vendor forks) and keep it first on PATH","Smoke-test `kubectl version --client -o json` after any kubectl change","Remove wrapper scripts around kubectl that emit extra text"],"tags":["kubectl","version-parsing","cli"],"backgroundTag":"kubectl-version-parse-failed","analyzedSha":"a1189de023efc32d4b8e11f395acc678aa555011","analyzedAt":"2026-09-05T12:09:27.064Z","contentChangedAt":"2026-09-05T12:09:27.064Z","schemaVersion":2},"datasetVersion":"2026-09-12T17:17:11.597Z"}