skip to content

How does Helm's oci:// reference address a chart, on the command line and in a Chart.yaml dependency?

level: juniorimportance: must knowfreq 74%

answer

  1. Two distribution targets, one has no index
  2. The last path segment is not decoration
  3. The tag carries the version
  4. Chart.yaml splits the reference in two
  5. No helm repo add step at all

basics

~20 s

An oci:// reference is a registry path whose last segment is the chart name and whose tag is the chart version. Commands take the whole path; a Chart.yaml dependency puts the path without the chart name in repository, and the chart name in name.

solid answer

~40 s

A chart in a registry is addressed as `oci://<host>/<path>/<chart-name>`, and the chart version is the tag. On the command line you pass the full reference and the version separately: `helm install tiles oci://registry.example.internal/platform-charts/tileserver --version 2.7.14`. The same form works for `helm upgrade`, `helm pull`, `helm template` and `helm show`. In a `Chart.yaml` dependency the reference is split: `repository` holds `oci://registry.example.internal/platform-charts` **without** the chart name, `name` holds `tileserver`, and `version` holds the version or range. Nothing is registered first — there is no `helm repo add` step for a registry, because the reference itself is the location. Pin an exact `--version` in automation: with no index to resolve against, the version you get is whatever tag the reference lands on.

code

bash · 3 lines
bash
helm install tiles oci://registry.example.internal/platform-charts/tileserver --version 2.7.14
helm show chart oci://registry.example.internal/platform-charts/tileserver --version 2.7.14
helm pull oci://registry.example.internal/platform-charts/tileserver --version 2.7.14

go deeper

for a junior

Be able to write the reference from memory: oci://host/path/chartname, with the version passed as --version. Know that no helm repo add step exists for a registry.

for a middle

Explain why the Chart.yaml dependency splits the reference across repository and name, and how Helm resolves a version range when there is no index.yaml to read.

for a senior

Show the discipline of pinning exact versions in CI and in dependency declarations, and explain why a floating reference to a registry is riskier than a floating reference to an indexed repository.

for a principal

Own the naming convention: which registry path charts live under, how it relates to image paths, and how that layout maps onto the access control your registry can express.

## Two ways Helm finds a chart Helm has always been able to fetch a chart from a **classic chart repository**: an HTTP server holding an `index.yaml` that lists every chart name, every version, and the URL of each `.tgz`. You register that server once with `helm repo add`, Helm caches its `index.yaml`, and afterwards you name charts as `myrepo/tileserver`. An **OCI registry** — the same kind of registry that stores container images — is the other distribution target. Here there is no index and nothing to register. The chart's *address is the reference itself*, written with the `oci://` scheme. ## The shape of the reference ``` oci://registry.example.internal/platform-charts/tileserver ^ host ^ path ^ chart name ``` Two rules matter and they are the source of nearly every beginner mistake: 1. **The last path segment is the chart name.** It is not decoration — it must match the `name` field in the chart's `Chart.yaml`. 2. **The chart version is the tag.** You do not write it into the URL with a colon on the command line; you pass `--version`. A chart at version `2.7.14` lives at the tag `2.7.14`. ## On the command line Every command that takes a chart argument takes an `oci://` reference: ```bash helm install tiles oci://registry.example.internal/platform-charts/tileserver --version 2.7.14 helm upgrade tiles oci://registry.example.internal/platform-charts/tileserver --version 2.7.15 helm pull oci://registry.example.internal/platform-charts/tileserver --version 2.7.14 helm show chart oci://registry.example.internal/platform-charts/tileserver --version 2.7.14 helm template tiles oci://registry.example.internal/platform-charts/tileserver --version 2.7.14 ``` `helm template` and `helm show` still need to reach the registry — they render or read locally, but the chart has to be fetched first. What none of these need is a prior `helm repo add`; trying to add a registry as a repository is a category error, because a registry has nothing shaped like an `index.yaml` for Helm to cache. ## In a Chart.yaml dependency When one chart depends on another, the reference is **split across two fields**, and this is where people most often get it wrong. The `repository` field holds the path *up to but not including* the chart name; the chart name goes in `name`: ```yaml apiVersion: v2 name: tileserver-platform version: 1.4.0 dependencies: - name: tileserver version: "2.7.14" repository: "oci://registry.example.internal/platform-charts" ``` Helm joins `repository` and `name` to build `oci://registry.example.internal/platform-charts/tileserver`, then treats `version` as the tag to fetch. Putting the chart name into `repository` as well produces a doubled path that the registry does not have. The `version` field may be an exact version or a SemVer range. With a classic repository Helm resolves a range against the cached `index.yaml`; for an `oci://` dependency there is no index, so Helm asks the registry for the tags published under that path and resolves the range against those. The result is written to the chart's lock file and the chosen version is vendored, exactly as it is for a classic repository — the resolution *source* is what differs, not the mechanism around it. ## Pin the version Because there is no index describing what exists, be explicit. In CI, in a `Chart.yaml` dependency and in any command a human runs against production, name the exact version. A floating reference to a registry is a reference whose meaning is decided by whoever last pushed a tag, and unlike a classic repository there is no local index cache to tell you after the fact what the set of candidates was at the time. ## Versions of Helm OCI support is not new or experimental. It has been generally available since Helm 3.8, and the environment variable that used to gate the feature has been unnecessary ever since — if you see it set in a pipeline, it is a leftover. Helm 4 kept the reference syntax and the command set identical, so an `oci://` reference written for Helm 3 works unchanged.

  • Can the version field of an oci:// dependency be a SemVer range rather than an exact version?
    Yes. Helm cannot consult an index.yaml for a registry, so it asks the registry for the tags published under that path and resolves the range against them. The resolved version is then recorded and vendored the same way a classic-repository dependency is. In automation an exact version is still the safer choice, because the candidate set is whatever someone has pushed rather than a cached index you can inspect afterwards.
  • A colleague's Chart.yaml has repository set to oci://registry.example.internal/platform-charts/tileserver and name set to tileserver. What happens?
    Helm joins the two, so it looks for a chart at .../platform-charts/tileserver/tileserver, which does not exist, and dependency resolution fails against that path. The repository field must stop one segment short: it holds the path the chart sits in, and the chart name is supplied separately by the name field.
  • Does helm template work against an oci:// reference without a cluster?
    Rendering is local, but the chart still has to be fetched, so the command needs network access to the registry and credentials if the path is private. It does not need a cluster or a kubeconfig unless the chart's templates ask about cluster capabilities. Pulling the chart once and rendering the local .tgz is the usual pattern for an offline or restricted build.

A classic chart repository is a library catalogue you consult by name; an OCI reference is a street address you drive straight to. Nobody registers an address with the post office first.

saying these in an interview costs you the question

  • Says you must helm repo add an OCI registry first
  • Puts the chart name inside the repository field as well
  • Thinks the tag is unrelated to the chart version
  • Claims OCI charts still need an experimental environment variable
  • Assumes a range in an oci:// dependency resolves against index.yaml
  • Writes the version into the URL instead of --version

context