GoogleContainerTools/skaffold · error
couldn't get kubectl minor version: %w
Error message
couldn't get kubectl minor version: %w
What it means
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).
Source
Thrown at pkg/skaffold/kubectl/version.go:71
// CheckVersion warns the user if their kubectl version is < 1.12.0
func (c *CLI) CheckVersion(ctx context.Context) error {
comp, err := c.CompareVersionTo(ctx, 1, 12)
if err != nil {
return err
}
if comp < 0 {
return errors.New("kubectl version 1.12.0 or greater is recommended for use with Skaffold")
}
return nil
}
func (c *CLI) CompareVersionTo(ctx context.Context, vMajor, vMinor int) (int, error) {
v := c.Version(ctx)
majorInt, err := strconv.Atoi(v.Major)
if err != nil {
return 0, fmt.Errorf("couldn't get kubectl minor version: %w", err)
}
// Some patched versions get a '+' suffix.
minorInt, err := strconv.Atoi(strings.TrimRight(v.Minor, "+"))
if err != nil {
return 0, fmt.Errorf("couldn't get kubectl minor version: %w", err)
}
if majorInt > vMajor {
return 1, nil
}
if majorInt == vMajor {
if minorInt > vMinor {
return 1, nil
}
if minorInt == vMinor {
return 0, nil
}View on GitHub (pinned to a1189de023)
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
Example fix
// before: forked kubectl prints Major="v1" -> Atoi fails // after: install upstream kubectl so Version() returns Major="1", Minor="27" kubectl version --client=true -o json | jq -r '.clientVersion.major'
Defensive patterns
Strategy: validation
Validate before calling
out, err := exec.Command("kubectl", "version", "--client", "-o", "json").Output()
if err != nil {
return fmt.Errorf("kubectl unavailable: %w", err)
}
var v struct{ ClientVersion struct{ Major, Minor string } }
if json.Unmarshal(out, &v) != nil || v.ClientVersion.Major == "" {
return errors.New("kubectl returned non-standard version output; install upstream kubectl")
} Type guard
func validKubectlVersion(major, minor string) bool {
_, err1 := strconv.Atoi(major)
_, err2 := strconv.Atoi(strings.TrimRight(minor, "+"))
return err1 == nil && err2 == nil
} Try / catch
cmp, err := cli.CompareVersionTo(ctx, 1, 20)
if err != nil {
var perr *strconv.NumError
if errors.As(err, &perr) {
return fmt.Errorf("kubectl version output unparseable (%s); reinstall upstream kubectl: %w", perr.Num, err)
}
return err
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- kubectl delete: %w
- `apply` requires at least one manifest argument
- `exec` requires exactly one action to execute
- `config-dependencies add` requires exactly one file path arg
- `jobManifestPaths modify` requires exactly one manifest file
AI-assisted analysis of GoogleContainerTools/skaffold@a1189de023 (2026-09-05).
Data as JSON: /api/errors/4aeb0e3529aa04f0.
Report an issue: GitHub.