Helm local index cache interaction with CI/CD chart deployment
0 reputation · 16 Jun 2021, 15:40 UTC
0 reputation · 16 Jun 2021, 15:40 UTC
The goal is to guarantee that Helm selects the most recent chart version available in a remote repository when executing install, upgrade, template, dependency update, or lint commands inside an automated CI/CD workflow, without requiring a manual helm repo update step.
However, Helm’s local repository index cache has no built‑in TTL and is reused indefinitely until explicitly refreshed. This can cause the cached index to serve stale chart metadata, leading to older chart versions being pulled or referenced, which affects reproducibility and may introduce known vulnerabilities. The same staleness propagates to any Helm sub‑command that reads the index.
35275 reputation · 16 Jun 2021, 22:14 UTC
No — Helm 3 offers no TTL, expiry, or auto-refresh setting for the local repository index cache, and there is no supported flag to make install, upgrade, template, lint, or dependency update refresh the index first. The cached index.yaml (under HELM_CACHE_HOME, typically ~/.cache/helm/repository) is reused indefinitely until you run helm repo update or delete the file. The only reliable fix is pipeline-level: refresh the index as an explicit early step in every job.
Confirmed: every Helm sub-command that resolves chart versions from a classic HTTP chart repository reads the local cached index. If the cache is stale, helm upgrade without --version silently selects the newest version the cache knows about, not the newest published. The likely explanation for what you're seeing in CI is long-lived self-hosted runners with a persistent cache directory — the index from a job hours or days ago keeps being served. Ephemeral runners (fresh container per job) rarely show this because the cache starts empty and the update step is effectively mandatory.
helm repo add myrepo https://charts.example.com
helm repo update myrepo # scoped to one repo to save time
helm upgrade --install myapp myrepo/myapp --namespace prodhelm search repo myrepo/myapp --versions | head -5helm repo update unconditionally — don't try to be clever with file timestamps, since the cache path varies with HELM_CACHE_HOME/XDG settings. Confirm it with helm env before scripting any deletion.helm install oci://...): there is no local repo index at all, so this entire class of staleness disappears. You still need explicit version tags for reproducibility.A stale index means "latest" is not a stable value: two environments deployed at different times, or on different agents with different cache ages, can resolve the same command to different chart versions. That breaks reproducibility and can leave one environment on a chart with known issues while another is current. Note the deeper caveat: even with a perfectly fresh index, "always latest" is inherently non-reproducible — a chart published mid-pipeline changes what gets deployed. For anything beyond dev, pin exact versions with --version or a Chart.lock, and use the fresh index only to discover what versions exist.
This applies to Helm 3 against classic HTTP(S) chart repositories; Helm 2 is end-of-life. To prove the behavior on your own runner: add a repo, note the newest version via helm search repo --versions, publish a newer chart, and re-run the search without helm repo update — the new version will be absent until you refresh. Checking the index file's modification time in the cache directory confirms it only changes on an explicit update.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.