skip to content

Chart Repositories

helm repo add and update against an index.yaml repository, a stale cache hiding a new version, helm search repo versus search hub, and --version pinning an install. What a junior is asked to type first.

part ofHelmoverview, primer and where to startread it →
on this pageshow

questions

4

What does `helm repo add` store locally, and why does a newly published chart version stay invisible until `helm repo update`?

level: juniorimportance: must knowfreq 88%

answer

  1. Two files land on your machine
  2. One lists repos, one is the catalogue
  3. Helm never re-fetches the catalogue on its own
  4. repositories.yaml plus a cached index.yaml
  5. HELM_REPOSITORY_CONFIG and HELM_REPOSITORY_CACHE

basics

~20 s

helm repo add saves a name-to-URL entry in your local repositories.yaml and downloads that repository's index.yaml into a cache directory. Helm resolves chart names from that cached copy and never refreshes it on its own, so a version published after your last helm repo update is invisible.

solid answer

~50 s

`helm repo add <name> <url>` does two things on your machine: it appends an entry to `repositories.yaml` (under `HELM_REPOSITORY_CONFIG`) and it immediately downloads that repository's `index.yaml` into the cache directory named by `HELM_REPOSITORY_CACHE`. That cached index is the *catalogue*: it lists every chart name, every published version, each version's `appVersion`, digest, and the download URL of the `.tgz`. When you run `helm install rel monitoring/monitoring-stack --version 4.11.2`, Helm looks the coordinates up in the cached file and then downloads the tarball - it does **not** re-fetch the index first. So a chart version published five minutes ago is simply not in your copy, and the install fails saying no chart version was found, with a hint to try `helm repo update`. `helm repo update` re-downloads the index for every added repo (or one named repo); `helm repo list` shows the entries; `helm repo remove` drops the entry and its cached index.

code

bash · 4 lines
bash
helm repo add monitoring https://charts.example.internal/monitoring
helm repo update monitoring
helm search repo monitoring/monitoring-stack --versions
helm env | grep HELM_REPOSITORY

go deeper

for a junior

Be ready to type the two commands in order and say what each one touches: add records the name and URL and grabs the catalogue once; update re-downloads that catalogue. Recognise the not-found error and reach for update before anything else.

for a middle

Explain the mechanics: which file holds the repo list, which directory holds the cached index, what an index entry actually contains, and why resolution reads the cache instead of the network.

for a senior

Show the triage: run helm env to find the real cache path on the box you are on, distinguish a stale catalogue from a genuinely missing publication, and know that offline search results prove nothing about the live repository.

for a principal

Own the pipeline consequence - unconditional refresh steps, pinned versions, and a policy on what CI is allowed to cache - so that a deploy's chart selection is never decided by whatever state a runner happened to keep.

### Two files, two roles A classic Helm chart repository is nothing more than a web server that serves an `index.yaml` plus a set of packaged `.tgz` charts. Everything `helm repo add` does happens on *your* machine - it does not register you with the server, and it does not tell the cluster anything. The first artefact is **`repositories.yaml`**, the list of repositories you have added: a name, the base URL, and any credential or TLS settings you supplied. Its location is `HELM_REPOSITORY_CONFIG`. This is per-user CLI state; nothing about it is stored in the cluster and nothing about it travels with a chart. The second is the **cached index**, written under `HELM_REPOSITORY_CACHE` (one file per repository). `helm env` prints both paths on any machine, which is the fastest way to answer "where is Helm actually reading from here?" during triage. ### What `index.yaml` contains The index is a full catalogue of the repository, not a pointer to one chart. For each chart name it holds an entry per published version, and each entry carries the chart `version`, the application's `appVersion`, a description, a creation timestamp, a `digest`, and one or more `urls` giving where the `.tgz` can be downloaded. An internal repository serving an 18-chart umbrella plus its history can easily reach a couple of thousand entries - a monitoring repository in one shop I have seen listed 2,317 chart versions in a single file - which is why `helm repo update` on a slow link is not instant. ### Why the cache goes stale, by design `helm repo add` fetches the index once, at add time (which is also why a typo'd URL fails immediately, reporting that the URL is not a valid chart repository or cannot be reached). After that, Helm treats the cached copy as authoritative until you refresh it. Resolution of `monitoring/monitoring-stack` at install, upgrade, pull, template or search time reads the cached file only. There is no TTL, no background refresh, and no automatic re-fetch on a miss. So the classic junior-day incident is: a colleague publishes `monitoring-stack` 4.11.2, tells you to install it, and your `helm install` fails with an error saying no chart version was found for that chart, plus the hint to try `helm repo update`. You run `helm repo update` and the same command now succeeds. Nothing was wrong with the repository; your catalogue was simply older than the publication. The mirror image is just as common and more confusing: `helm search repo monitoring/monitoring-stack --versions` happily lists versions while you are on a plane, because search is served entirely from the cache. Offline results are not proof the repository still exists or still holds those versions. ### The rest of the command family - `helm repo list` prints the configured name/URL pairs (`-o json` if you are scripting it). - `helm repo update` refreshes every configured repository; passing one or more names refreshes only those, which matters when one repo in your list is unreachable and you do not want the whole command to grind. - `helm repo remove <name>` deletes the entry and its cached index files. - Re-adding a name that already exists is rejected unless you pass `--force-update`, which replaces the existing entry - the flag to reach for when a repository moves to a new URL. ### Where this bites in CI A fresh CI runner has an empty `repositories.yaml`, so any pipeline that installs from a repository must `helm repo add` and `helm repo update` as explicit steps; "it works on my laptop" here means "my laptop has state your runner does not." The opposite failure appears when a pipeline caches the runner's Helm home to save a few seconds: now the runner has a *stale* index that it never refreshes, and the deploy job silently keeps selecting the version that was newest whenever the cache was seeded. If you cache anything, cache the packaged charts, not the index - and keep the `helm repo update` step unconditional. ### The boundary worth naming All of the above is the classic index-based repository. A chart referenced as `oci://...` is addressed directly in a registry and has no `index.yaml` to add, update or search - so none of this cache machinery applies to it, which is a separate topic in its own right. And this is purely client-side state: how the server produces or serves that index belongs to whoever runs the repository.

  • Does `helm install` ever refresh the repository index by itself?
    No. Install, upgrade, pull, template and search all resolve chart coordinates from the cached index and go straight to downloading the `.tgz`. The only refresh is an explicit `helm repo update`, or the one-off fetch that `helm repo add` performs when you first add the repository. That is why Helm's not-found error suggests running `helm repo update` rather than retrying.
  • Your CI pipeline caches the runner's Helm home directory between builds and deploys keep landing on an old chart. What happened?
    The cached home carries a `repositories.yaml` that already contains the repo, so a conditional `helm repo add` step is skipped, and the equally stale cached index is never refreshed. Helm then resolves to the newest version that existed when the cache was seeded. Fix it by running `helm repo update` unconditionally on every build, and by pinning `--version` so the resolved chart is not a moving target at all.
  • How do you point an existing repository name at a new URL?
    Re-run `helm repo add` with the same name and the new URL plus `--force-update`; without that flag Helm refuses because the name is already taken. The alternative is `helm repo remove <name>` followed by a plain `helm repo add`, which also clears the cached index for that name. Either way, follow with `helm repo update` so the catalogue you resolve against comes from the new location.

The cached index.yaml is a printed mail-order catalogue. Ordering from page 12 works fine, but the warehouse adding a new product does not reprint the copy sitting on your desk - helm repo update is you asking for this season's edition.

saying these in an interview costs you the question

  • Claims helm install refreshes the repository index automatically
  • Thinks helm repo add uploads or publishes a chart
  • Says repositories are registered in the cluster, not the client
  • Confuses helm repo update with upgrading installed releases
  • Believes the cached index expires on a timer
  • Cannot say where repositories.yaml or the index cache lives

context

open as a page

What does `helm pull --version` fetch, and when would you pull a chart instead of installing it straight from the repository?

level: middleimportance: should knowfreq 45%

basics

~20 s

helm pull downloads a chart's packaged .tgz from a repository to the local filesystem without touching a cluster, with --version selecting an exact published version instead of the newest. Pull when you need to inspect, diff, mirror or vendor the exact artefact rather than install it.

open as a page

Which `helm repo add` flags reach a private chart repository behind basic auth and an internal CA, and where do the credentials land?

level: seniorimportance: should knowfreq 50%

basics

~20 s

Use --username and --password for basic auth, --ca-file to trust an internal CA, and --cert-file/--key-file for client certificates. Helm writes those credentials in plaintext into repositories.yaml, so on shared or CI machines pass them per-command with --repo instead of persisting them.

open as a page

What is the difference between `helm search repo` and `helm search hub`?

level: middleimportance: nice to knowfreq 31%

basics

~20 s

helm search repo searches only the cached indexes of repositories you have added, works offline, and returns coordinates you can install immediately. helm search hub queries Artifact Hub over the network across thousands of public repositories and returns listing pages you cannot install from until you add the repository.

open as a page