skip to content

Dependencies & Repositories

Where a chart's parts come from and where the chart itself goes: subcharts declared with version ranges and conditions, a lockfile that pins them, and distribution over a classic repository index or an OCI registry. Umbrella charts are where teams get stuck.

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

explore

questions

30

In a Helm Chart.yaml dependency, what does the condition field do, and what happens if its values path is absent?

level: juniorimportance: must knowfreq 62%

answer

  1. A per-dependency on/off switch
  2. Declared beside name and version
  3. Points at a dotted values path
  4. Must resolve to a real boolean
  5. Missing path means no opinion

basics

~20 s

condition names a dotted values path, such as database.enabled, on a Chart.yaml dependency entry. If that path resolves to a boolean, it decides whether Helm renders that subchart at all. If the path is absent, the condition is ignored and the dependency stays enabled.

solid answer

~50 s

In `Chart.yaml`, each entry under `dependencies` may carry a `condition`: one values path, or a comma-separated list of paths, that switches the subchart on or off. Before rendering, Helm evaluates the paths against the values the release is being rendered with. The first path that resolves to a **boolean** decides; a path that does not exist is skipped silently; a value that is not a boolean is ignored with a warning. If nothing resolves, the dependency keeps its default state, which is enabled. Disabled means the subchart's templates produce nothing at all - no objects in the manifest, no hooks. It does not mean the dependency is gone: it is still declared, still pinned in `Chart.lock`, still vendored under `charts/` and still shipped inside the packaged `.tgz`. So a caller turns a bundled component off with `--set db.enabled=false` or a values file, without forking the chart.

code

yaml · 11 lines
yaml
apiVersion: v2
name: billing
version: 4.2.1
dependencies:
  - name: postgresql
    version: 15.3.2
    repository: https://charts.example.internal
    condition: postgresql.enabled
  - name: billing-lib
    version: 2.9.0
    repository: https://charts.example.internal

go deeper

for a junior

Be ready to say where the field lives - a dependency entry in Chart.yaml - and to name the flag that turns a bundled component off at install time without editing the chart.

for a middle

Explain the resolution order: comma-separated paths tried left to right, first boolean wins, missing paths skipped, non-booleans warned about and ignored, default enabled.

for a senior

Show that you verify rather than trust. A misspelled path fails silently, so demonstrate rendering with the real values first and reading what the chart actually produced.

for a principal

Own the authoring convention: which switches a shared chart exposes, what their defaults are, and why one conditioned chart beats a forked copy per environment across a fleet of services.

### Where the field lives A chart declares what it bundles in `Chart.yaml`, under `dependencies`. Each entry has a `name`, a `version` range and a `repository`, and may add `alias`, `tags`, `import-values` and `condition`. `condition` is the on/off switch for that one dependency: ```yaml apiVersion: v2 name: billing version: 4.2.1 dependencies: - name: postgresql version: 15.3.2 repository: https://charts.example.internal condition: postgresql.enabled ``` The string is a **values path**, written with dots, addressed from the top of the values tree the release is rendered with. It is not a template expression - there is no `{{ }}`, no function, no comparison. It can only point at something that is already a boolean. ### How Helm resolves it Before any template is executed, Helm walks the dependency list and computes an `enabled` flag for every entry. Everything starts enabled. For an entry with a condition, Helm splits the string on commas and tries each path in order: - the first path that resolves to a boolean wins, and evaluation stops there; - a path that does not exist in the values is skipped, and the next path is tried; - a path that exists but holds something else - the *string* `"false"`, a number, a map - is not usable, and Helm logs a warning and moves on; - if no path yields a boolean, the condition contributes nothing and the dependency keeps whatever state it already had. Two consequences bite people. First, resolution is **silent on failure**: a typo such as `postgresql.enable` is simply a path that does not exist, so the subchart renders and no error is printed. Second, YAML types matter: `postgresql.enabled: "false"` is a quoted string, not a boolean, and it will not disable anything. `--set postgresql.enabled=false` produces a real boolean; `--set-string` would not. The comma-separated form exists so a chart can honour more than one switch, for example a specific key and a shared fallback: `condition: postgresql.enabled,global.bundledDatabase`. The first of those that actually exists in the caller's values decides, so a specific per-chart key overrides a broad one only because it is listed first. ### What "disabled" actually means A disabled dependency is **not rendered**. None of its templates execute, so none of its objects appear in the manifest Helm applies and stores with the revision, and none of its hook manifests exist to be run. Its `NOTES.txt` contributes nothing. From the cluster's point of view the subchart may as well not be in the chart. What does *not* change is packaging. The entry is still in `Chart.yaml`, still pinned in `Chart.lock`, still vendored as a `.tgz` under `charts/`, and still inside the parent's packaged archive. Enablement is a render-time decision taken from values; it is not a way to slim down a chart or to avoid fetching a dependency. ### Why charts are built this way The pattern exists so one chart can serve two shapes of deployment. A team ships a chart for a subscription-billing service that bundles a database subchart so a developer can `helm install` it on a laptop and get something that works. In production the same chart runs against a managed database, and the platform team passes `postgresql.enabled=false` plus an external host in a values file. There is one chart, one version stream, and no fork - the difference between the environments is data, reviewed in a values file, not a divergent copy of the templates. Chart authors therefore give the switch a default in the parent's own `values.yaml` (usually `enabled: true`, so the out-of-the-box install works) and document the key. Consumers flip it per environment. ### Checking it Because the failure mode is silence, verify rather than assume. Rendering locally with the exact values you intend to use shows precisely which objects the chart will produce, and grepping that output for the subchart's resources answers the question directly - before anything reaches a cluster.

  • A condition reads postgresql.enabled,global.bundledDatabase. How is that pair resolved?
    Helm tries the paths left to right and takes the first one that exists and holds a boolean, then stops. If `postgresql.enabled` is set anywhere in the release's values it decides, and `global.bundledDatabase` is never consulted. If only the second is set, it decides. If neither exists, the condition contributes nothing and the dependency stays enabled.
  • Does disabling a dependency stop helm dependency update from fetching it?
    No. Dependency resolution and vendoring happen from `Chart.yaml` alone, with no values in play, so the subchart is still downloaded into `charts/`, still pinned in `Chart.lock`, and still packaged inside the parent's `.tgz`. The condition is evaluated later, at render time, and only decides whether the vendored chart's templates execute.
  • Why does --set db.enabled="false" fail to disable a subchart?
    Quoting makes it the string `"false"`, and a condition only acts on a genuine boolean. Helm finds the path, sees a non-boolean, logs a warning and leaves the dependency enabled. Use `--set db.enabled=false`, or write `enabled: false` unquoted in a values file; never route it through `--set-string`.

A condition is the wiring for a light switch the installer leaves on the wall: the fixture ships with the house either way, and whoever moves in decides whether it draws power.

saying these in an interview costs you the question

  • Thinking a missing condition path disables the dependency
  • Writing condition as a template expression with curly braces
  • Expecting an error when the condition path is misspelled
  • Believing a disabled subchart is dropped from charts/ or the .tgz
  • Passing the quoted string "false" and expecting it to switch off
  • Assuming a disabled subchart's hooks still run

context

open as a page

What does an entry in a Helm chart's Chart.yaml dependencies list declare?

level: juniorimportance: must knowfreq 76%

basics

~20 s

Each dependencies entry declares one subchart the chart bundles: name is the chart to fetch, version is a SemVer range the fetched chart must satisfy, and repository says where to fetch it from. Optional fields such as alias refine that.

open as a page

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

level: juniorimportance: must knowfreq 74%

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.

open as a page

How do you publish a packaged Helm chart so others can install it with helm repo add?

level: juniorimportance: must knowfreq 66%

basics

~20 s

Collect the packaged .tgz files in one directory, run helm repo index on that directory to generate index.yaml, and serve the directory over HTTP. A chart repository is static files - no chart-server software is required.

open as a page

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%

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.

open as a page

In Helm, how does a parent chart's values.yaml pass values down to a subchart?

level: juniorimportance: must knowfreq 74%

basics

~10 s

The parent sets a subchart's values under a top-level key named for that dependency, or for its alias when the dependency declares one. Those parent values override the subchart's own values.yaml defaults.

open as a page

What is the difference between helm dependency update and helm dependency build?

level: middleimportance: must knowfreq 72%

basics

~20 s

helm dependency update re-resolves the ranges in Chart.yaml, rewrites Chart.lock and refills charts/. helm dependency build ignores the ranges and fetches exactly what Chart.lock already pins, so pipelines run build and authors run update deliberately.

open as a page

In Helm, what does the global block in a values file make available to a chart tree?

level: middleimportance: must knowfreq 61%

basics

~10 s

global is a reserved top-level values key that Helm copies into every chart in the dependency tree. Parent, subcharts and grandchildren all read the same values at .Values.global, at any depth.

open as a page

What does Helm record in a chart's Chart.lock, and what are its digest and generated fields?

level: juniorimportance: should knowfreq 48%

basics

~10 s

Chart.lock records the exact subchart versions Helm resolved from the ranges in Chart.yaml, each with its name, repository and version. The digest field hashes those dependency declarations; generated is the timestamp of the resolution.

open as a page

A bundled Helm subchart still renders even though you set enabled: false. Where must that value actually live?

level: middleimportance: should knowfreq 45%

basics

~20 s

A dependency's condition path is looked up in the values the release is rendered with, addressed from the top of that tree. Setting enabled: false inside the subchart's own values.yaml, or under the wrong key, leaves the path unresolved - and an unresolved path is ignored silently, so the subchart renders.

open as a page

What forms can the repository field of a Helm chart dependency take?

level: middleimportance: should knowfreq 52%

basics

~20 s

A Helm dependency's repository can be an https chart-repository base URL, an oci:// registry path that Helm appends the chart name to, a file:// path to a chart in the same tree, an @name reference to a locally added repository, or empty when the chart is already vendored under charts/.

open as a page

How does Helm authenticate to a private OCI registry, and where does it keep those credentials?

level: middleimportance: should knowfreq 56%

basics

~20 s

Run helm registry login against the registry host, optionally reading the password from standard input. Helm writes the credential into its own registry config file, named by HELM_REGISTRY_CONFIG, and every later oci:// operation against that host uses it. helm registry logout removes the entry.

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

How do you address a value inside a nested Helm subchart with --set?

level: middleimportance: should knowfreq 49%

basics

~10 s

Write the dotted path down the dependency tree from the top-level chart: --set worker-gpu.encoder.threads=12. Each segment is a dependency's name — or its alias — and --set global.x=y reaches every chart at once.

open as a page

You flip a bundled database subchart off on a live Helm release. What happens to the objects it already deployed?

level: seniorimportance: should knowfreq 36%

basics

~20 s

They are deleted. On upgrade Helm compares the previous revision's stored manifest with the newly rendered one and removes what disappeared, so a disabled subchart takes its objects - including any it rendered to hold data - with it. Only helm.sh/resource-policy: keep spares one.

open as a page

When does a Helm umbrella chart that declares every service as a subchart stop paying off?

level: seniorimportance: should knowfreq 40%

basics

~20 s

It stops paying off once the services in it stop sharing a lifecycle. One umbrella means one release, one revision and one rollback, so every team's change deploys everything, one failing subchart fails the whole upgrade, and the single stored release record keeps growing.

open as a page

Would you commit a Helm chart's charts/ directory of vendored subchart tarballs, or only Chart.lock?

level: seniorimportance: should knowfreq 52%

basics

~20 s

Always commit Chart.lock. Commit the charts/ tarballs only when you need a build that fetches nothing and survives an upstream repository disappearing, accepting binary blobs in review, repository growth, and drift that Helm will not detect at install time.

open as a page

Why does helm search repo find nothing for charts in an OCI registry, and how do you discover versions?

level: seniorimportance: should knowfreq 40%

basics

~20 s

helm search repo reads cached index.yaml files from repositories added with helm repo add, and a registry has neither an index nor a repository entry. Discovery has to come from the registry's own tag listing, from a catalogue you publish, or from versions pinned in Chart.yaml.

open as a page

Why must an already-published Helm chart version never be overwritten with new content?

level: seniorimportance: should knowfreq 47%

basics

~20 s

Nothing in Helm enforces it, but every consumer treats chart name plus version as an identity: cached indexes, pinned dependencies and stored release records all resolve by version. Overwriting makes one coordinate mean two different things. Bump the version instead.

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

Chart.lock pins your subchart versions - what else must you pin so a chart renders identically in six months?

level: principalimportance: should knowfreq 38%

basics

~20 s

Chart.lock pins only which subchart versions are fetched, not their bytes. Reproducing a render also means fixing the parent chart artefact, the values files, image references, the Helm CLI version and the cluster API versions the render assumes.

open as a page

Would you move your team's Helm chart distribution to an OCI registry, and what breaks if you do?

level: principalimportance: should knowfreq 26%

basics

~20 s

Usually yes for internal charts consumed by automation: one artefact system, one credential model, no static index to regenerate. The costs are lost search and browsability, every consumer needing oci:// support, and registry retention now able to remove a chart a static file server would have kept.

open as a page

How do you choose between publishing your Helm charts to a static index.yaml repository and to a registry?

level: principalimportance: should knowfreq 40%

basics

~20 s

Both channels ship the identical .tgz, so decide on operations, not features: a static index is one file on any web host carrying the whole catalogue; a registry reuses the credentials, replication and retention you already run.

open as a page

In a Helm umbrella chart with fourteen subcharts, when do you route a setting through global instead of repeating it per subchart?

level: principalimportance: should knowfreq 37%

basics

~20 s

Use Helm's global block only for facts that belong to the installation itself — registry mirror, storage class, cluster domain — and that most subcharts genuinely read. Everything else is cheaper duplicated per subchart, where it diffs cleanly and its blast radius is one chart.

open as a page

How does Helm resolve a chart dependency's tags list, and what wins when condition and tags disagree?

level: middleimportance: nice to knowfreq 24%

basics

~20 s

A dependency's tags list in Chart.yaml is matched against a top-level tags map in the release's values. If any of its tags is true the dependency is enabled; if every tag it names is present and false it is disabled; if none is set it stays enabled. A resolved condition always overrides tags.

open as a page

In a Helm chart's dependencies, what does the alias field do?

level: middleimportance: nice to knowfreq 32%

basics

~20 s

alias gives a dependency a different name inside the parent chart, which is what lets the same chart be declared twice in one Chart.yaml. Helm then treats each entry as a separate subchart named by its alias, with its own values key.

open as a page

What does helm push upload to an OCI registry, and where does the target reference come from?

level: middleimportance: nice to knowfreq 28%

basics

~20 s

helm push takes an already-packaged .tgz and a base registry path. The chart name and version come from Chart.yaml inside the archive, not from the command, so the destination omits both. If a matching .prov file sits beside the .tgz it is uploaded alongside automatically.

open as a page

What does helm repo index --merge do that regenerating the index alone does not?

level: middleimportance: nice to knowfreq 34%

basics

~20 s

helm repo index builds index.yaml from only the packages present in the directory. --merge folds an existing index.yaml into that result, so versions whose tarballs are not in that directory keep their entries instead of disappearing.

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

What does an import-values entry on a Helm chart's dependency actually do?

level: seniorimportance: nice to knowfreq 16%

basics

~20 s

import-values, listed on a dependency in Chart.yaml, copies values upward from the subchart into the parent's values — either a block the child publishes under exports, or an explicit child path mapped to a parent path.

open as a page