Skip to content

[Helm] ArgoCD-provided .Capabilities.KubeVersion.Version is inconsistent with Helm #26330

@fuljo

Description

@fuljo

Checklist:

  • I've searched in the docs and FAQ for my answer: https://bit.ly/argocd-faq.
  • I've included steps to reproduce the bug.
  • I've pasted the output of argocd version.

Describe the bug

If you deploy an Helm Application that uses .Capabilities.KubeVersion.Version in its chart's template, the result is inconsistent if the user does not explicitly specify helm.kubeVersion.

  • Helm (tested with v3.19.5) outputs a format like v1.34.0.
  • ArgoCD (tested with v3.3.0) outputs a format like v1.34.

This is making the installation of kube-prometheus-stack fail because it relies on the full semver to pull the kubectl image (see https://github.com/prometheus-community/helm-charts/blob/a3300192e5ff039d59db6209811f21fda9033b80/charts/kube-prometheus-stack/charts/crds/templates/upgrade/job.yaml#L78).

Other charts that rely on reading the full value (major.minor.patch) may fail too.

To Reproduce

  1. Produce a minimal chart with this template:
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: debug-cm
    data:
      direct: "{{ .Capabilities.KubeVersion.Version }}"
  2. Render it with Helm
    helm template debug-chart ./debug-chart --debug
  3. Deploy an ArgoCD application that uses the chart
    apiVersion: argoproj.io/v1alpha1
    kind: Application
    metadata:
      name: debug-app
      namespace: argocd
    spec:
      destination:
        server: https://kubernetes.default.svc
        namespace: default
      project: default
    
      sources:
        - repoURL: https://github.com/example/example.git
          path: debug-chart
          targetRevision: "main"
    

Expected behavior

Helm and ArgoCD shall have the same behavior.

Version

argocd: v3.2.3+unknown
  BuildDate: 2025-12-29T04:22:33Z
  GitCommit:
  GitTreeState:
  GitTag: 3.2.3
  GoVersion: go1.25.5 X:nodwarf5
  Compiler: gc
  Platform: linux/amd64
argocd-server: v3.3.0
  BuildDate: 2026-02-02T07:28:36Z
  GitCommit: fd6b7d5b3cba5e7aa7ad400b0fb905a81018a77b
  GitTreeState: clean
  GitTag: v3.3.0
  GoVersion: go1.25.5
  Compiler: gc
  Platform: linux/amd64
  Kustomize Version: v5.8.0 2025-11-09T14:39:49Z
  Helm Version: v3.19.4+g7cfb6e4
  Kubectl Version: v0.34.0
  Jsonnet Version: v0.21.0

Possible cause
This might happen because the value that ArgoCD passes to helm template --kube-version <value> is gotten from this cached entry, which explicitly prints just <major>.<minor>:

func (db *db) getLocalCluster() *appv1.Cluster {
initLocalCluster.Do(func() {
info, err := db.kubeclientset.Discovery().ServerVersion()
if err == nil {
localCluster.Info.ServerVersion = fmt.Sprintf("%s.%s", info.Major, info.Minor)
localCluster.Info.ConnectionState = appv1.ConnectionState{Status: appv1.ConnectionStatusSuccessful}
} else {
localCluster.Info.ConnectionState = appv1.ConnectionState{
Status: appv1.ConnectionStatusFailed,
Message: err.Error(),
}
}
})
cluster := localCluster.DeepCopy()
now := metav1.Now()
cluster.Info.ConnectionState.ModifiedAt = &now
return cluster
}

NOTE: I've tried to track the source value down, but I'm not very familiar with the code.

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingtriage/pendingThis issue needs further triage to be correctly classified

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions