In Helm 4, what values does --wait accept, and what does omitting the flag do?
answer
- It stopped being a yes-or-no question
- Three names, one of them the old behaviour
- The bare flag and the missing flag differ
- Events and kstatus, not a poll loop
- Omitting it waits only on hooks
basics
~20 sIn Helm 4 --wait names a strategy, not a boolean: watcher (event-driven, kstatus-based), legacy (Helm 3's polling waiter), or hookOnly. Bare --wait means watcher; omitting it leaves hookOnly, so Helm does not wait for workloads.
solid answer
~40 sHelm 4 turned `--wait` from a boolean into a **strategy-valued** flag with three values. `watcher` is the new default judgement: it watches resources and decides readiness from their reported status using kstatus, driven by events rather than a poll loop. `legacy` is the Helm 3 waiter, kept for charts whose readiness the old polling behaviour judged the way a team expects. `hookOnly` limits waiting to hook resources. Because the value is optional, a bare `--wait` selects `watcher`, and a non-default value is written with an equals sign: `--wait=legacy`. **Omit the flag entirely and you get `hookOnly`**, which is the part that catches people out: `helm upgrade` returns success as soon as the API server has accepted the manifests, not when the app is serving. `--timeout` bounds whichever wait you choose.
code
bash · 10 linesCHART=oci://registry.internal/charts/invoice-worker
# No flag: hookOnly. Returns once the API server accepts the manifests.
helm upgrade --install invoice-worker "$CHART" --version 2.14.3 -n billing
# Bare flag: the watcher strategy, bounded by the timeout.
helm upgrade --install invoice-worker "$CHART" --version 2.14.3 -n billing --wait --timeout 12m
# Explicit value uses an equals sign.
helm upgrade --install invoice-worker "$CHART" --version 2.14.3 -n billing --wait=legacy --timeout 12mgo deeper
Be able to say that --wait decides whether Helm blocks until the release's resources are ready, that leaving it off means Helm does not wait for your workloads, and that --timeout is the separate flag that bounds the wait.
Name the three strategies and explain the difference between the bare flag and the missing flag. Be ready to say what watcher judges readiness from and why an event-driven watcher generalises better than a fixed per-kind poll loop.
Show you know what a zero exit code does and does not prove, and that you have made the deliberate choice about which strategy your pipelines use. Be able to explain how a Helm 3 script's bare --wait silently changes meaning under a Helm 4 CLI.
Own the org-level decision: whether every pipeline waits, what waiting costs in held CI capacity and blocked release trains, and how you migrate a fleet of scripts off the old boolean assumption without a flag day.
## The shape change In Helm 3, `--wait` was a boolean, off by default: pass it and Helm blocked until the release's resources looked ready, omit it and Helm returned as soon as the manifests were accepted. Helm 4 keeps the two behaviours but replaces the on/off switch with a **named strategy**, because "wait" was hiding a question the flag never let you answer: *who decides that the resources have arrived?* The three values are: - **`watcher`** - the modern path. Helm watches the resources it applied and derives readiness from the status they report, using kstatus' notion of a resource being current rather than a hand-rolled per-kind check. It is event-driven, so it reacts when the cluster tells it something changed instead of asking on a timer. - **`legacy`** - the Helm 3 waiter, preserved verbatim: a polling loop with per-kind readiness rules (pods ready, PVCs bound, Deployments at their minimum available replicas, Services with an address). It exists so a team whose charts were tuned against that exact judgement can keep it while they migrate. - **`hookOnly`** - wait only on hook resources, which is what Helm has always done regardless of the flag. Helm 4 simply gives that baseline a name. ## The two defaults people confuse There are two separate defaults here, and conflating them is the single most common error on this flag. **The flag's value is optional**, so a bare `--wait` with nothing after it resolves to `watcher`. That is why you write a non-default strategy with an equals sign - `--wait=legacy` - rather than as a space-separated word: with an optional-value flag, the equals form is the one that reliably attaches the value to the flag rather than leaving it as a stray argument. **Omitting the flag entirely resolves to `hookOnly`.** So Helm 4, exactly like Helm 3 with no `--wait`, does not wait for your workloads. The command's exit code means "the API server accepted these manifests", not "the application is running". A pipeline that treats a zero exit from `helm upgrade` as proof of a healthy deploy is wrong on both versions - it is just that in Helm 4 the wrongness has a name you can point at. ## Why watcher instead of the old loop The Helm 3 waiter knew a fixed set of kinds and how to judge each one. That works for a chart of Deployments and Services and degrades badly for a chart that installs custom resources, where the old logic had nothing to check and effectively considered the object done the moment it existed. A status-driven watcher generalises: any resource that reports its progress in the conventional way can be judged, and Helm learns about changes from watch events rather than re-listing on an interval, which is both faster to notice readiness and much lighter on the API server for a release with a lot of objects. `legacy` is there for the migration, not as a recommendation. The realistic reason to reach for it is that some resource in your chart is judged differently by the two strategies and you would rather ship today than re-diagnose readiness during an upgrade window. ## What it looks like in practice Take an invoice-rendering worker chart published to an OCI registry by CI. Deployed with no wait flag, the pipeline goes green in seconds and the workers may still be pulling their image. Deployed with `--wait --timeout 12m`, the pipeline goes green when the workers report ready, and takes roughly the 7m14s the rollout actually needs. Same chart, same cluster; the difference is entirely in what the exit code is allowed to mean. ## Things to get right when asked - `--wait` is not a duration. `--timeout` is the duration; `--wait` chooses *whether and how* readiness is judged, `--timeout` chooses *how long* that judgement gets. - Waiting is not free: the CI job holds its slot for the full rollout, and its own step limit must exceed `--timeout`. - A script carried over from Helm 3 that spelled the flag as a boolean value should be rewritten to name a strategy explicitly - and a script that passed a bare `--wait` now gets `watcher` rather than the old polling waiter, which is a behaviour change even though the command line did not move.
- A Helm 3 script passed a bare --wait and now runs against a Helm 4 CLI. What changed?The command line is unchanged but the behaviour is not: bare --wait now selects the watcher strategy rather than the Helm 3 polling waiter. Readiness is judged from reported resource status and driven by watch events, so a chart containing custom resources that the old waiter effectively ignored may now genuinely be waited on - which is usually an improvement, and occasionally a newly failing pipeline. Pin --wait=legacy if you need the old judgement while you investigate.
- What does a zero exit code from helm upgrade prove when no wait strategy was set?Only that Helm rendered the chart, the API server accepted every manifest, and any hooks completed. It says nothing about whether pods started, images pulled, or the service is answering. Treating that exit code as a deploy health signal is the classic mistake; if the pipeline needs to gate on the application actually running, it has to ask for a wait strategy and give it a realistic timeout.
- Why keep the legacy strategy at all if watcher is better?Migration. The old waiter has fixed per-kind rules, and a chart tuned against them can be judged differently by a status-driven watcher - a resource the old loop never really examined may now hold the release open, or vice versa. Keeping legacy lets a team move to Helm 4 without re-diagnosing readiness during an upgrade window, and treat the strategy switch as its own change with its own rollout.
The old flag asked 'should I wait?'; the new one asks 'whose judgement decides you have arrived?' - and if you never ask, only the hooks get a verdict.
saying these in an interview costs you the question
- Calls --wait a boolean in Helm 4
- Thinks omitting --wait still waits for pods
- Confuses --wait with a duration value
- Believes bare --wait selects the legacy waiter
- Says a zero exit code proves the app is healthy
- Assumes watcher polls the API on an interval