What does `helm upgrade` do with the previous release's values when neither --reuse-values nor --reset-values is passed?
answer
- It depends on what you passed
- Emptiness is the switch, not content
- One --set discards all the rest
- Stored user-supplied map, not chart defaults
- Ask explicitly with a reuse flag
basics
~20 sHelm's default is conditional: with no -f or --set on the upgrade, the previous release's user-supplied values carry forward. Pass even one value flag and those stored overrides are dropped, leaving only your new flags over the chart's defaults.
solid answer
~50 s`helm upgrade` neither always reuses nor always discards the last release's values — the default depends on whether *you* supplied any. If the command carries no `-f` and none of the `--set` family, Helm copies the previous revision's user-supplied values into the new revision, so a bare `helm upgrade rerank ./chart` is effectively a re-render with the same overrides. Supply one value flag and that set becomes the whole override map: the previous overrides are discarded and only what you passed is merged over the chart's `values.yaml`. That is why `helm upgrade rerank ./chart --set image.tag=2026.09.1` so often silently drops forty lines of settings the release had been running with. Chart defaults always come fresh from the chart you are installing now. If you want the old overrides kept, ask for it with `--reuse-values` or `--reset-then-reuse-values`.
code
bash · 11 lines# 1. Install with a full values file
helm install rerank ./reranker-chart -f prod-values.yaml
# 2. No value flags at all: the stored overrides are carried forward
helm upgrade rerank ./reranker-chart
# 3. One --set: prod-values.yaml's overrides are gone from this revision
helm upgrade rerank ./reranker-chart --set image.tag=2026.09.1
# 4. What the release is actually running on
helm get values rerankgo deeper
Memorise the conditional: no value flags means the previous overrides carry forward, any value flag means only what you passed survives. Be able to say which command shows a release's current overrides.
Explain that the switch is whether the command supplied any values at all, and that chart defaults are always read from the chart being installed now rather than from the previous release.
Show how you would catch a dropped override before it ships: diff the user-supplied values across revisions, render with a dry run, and insist that pipelines pass the complete values file every time.
Own the standard. Decide whether operators may ship a bare --set at all, and how you make the repository the only description of a release so an upgrade can never silently narrow it.
### What Helm actually has to decide A Helm release revision stores two things that matter here: the chart it was rendered from, and the revision's **user-supplied values** — the single map that the `-f` files and `--set` flags of that command produced. The chart's own `values.yaml` defaults are *not* part of that map; they stay in the chart and are merged underneath the user-supplied map at render time. So on every `helm upgrade`, Helm has exactly one question to answer: what is the new revision's user-supplied map? It has two candidate inputs — whatever this command passed, and whatever the previous revision stored. ### The default rule, stated exactly With none of `--reuse-values`, `--reset-values` or `--reset-then-reuse-values` on the command line, Helm applies a conditional: * If the command supplied **no values at all** — no `-f`, and none of `--set`, `--set-string`, `--set-json`, `--set-file`, `--set-literal` — the previous release's user-supplied values are copied into the new revision. * If the command supplied **anything**, that is the new revision's user-supplied map in full, and the previous one is discarded. It is all-or-nothing, and the switch is the *emptiness* of what you passed, not its content. A single `--set replicaCount=3` is enough to flip it. ### Why this is the classic first outage Picture a release installed from a forty-line values file: replica count, resource requests, an ingress host, a queue name, a feature flag. Six months later someone ships a build with `helm upgrade rerank ./chart --set image.tag=2026.09.1`. Helm renders the chart with its defaults plus that one override. The forty lines are gone. Replicas fall back to the chart default, the ingress host disappears, the feature flag reverts. The cruel part is that nothing errors: the render is valid, the apply succeeds, the release reaches `deployed`, and the first sign of trouble is the pager. The symmetric surprise is the other branch. A colleague runs a bare `helm upgrade rerank ./chart` expecting a clean re-install from chart defaults, and instead gets the same overrides they were trying to shake off — because with nothing passed, the stored map is copied forward. ### What the default never does It never carries the **old chart's** defaults forward. Defaults for the new revision are read from the chart you are installing now, so if a new chart version changes a default, that change lands. This is precisely what `--reuse-values` gives up: that flag folds the old chart's coalesced defaults into the values map as though you had typed them yourself, and they then mask the new chart's defaults. ### How to see it before it bites `helm get values <release>` prints the user-supplied map for the current revision; `helm get values <release> -a` prints the full computed set, chart defaults included; `--revision` points either of them at an older revision. Diffing the user-supplied map before and after an upgrade is the cheapest possible check. Rendering with `--dry-run=client` shows the manifests the command *would* produce, so a lost ingress host is visible before it ships rather than after. ### The habit that removes the whole class of bug Treat the values file in your repository as the complete description of the release, pass it with `-f` on every single upgrade, and never depend on stored values. Then the default rule works in your favour: you always supply values, the stored map is always replaced by the file, and what runs is what the repository says. Per-environment differences go in a second file passed after the base one. The moment an operator ships a change with a bare `--set`, the repository stops describing the release, and the next person who does pass the full file will appear to "revert" something they never touched. ### First install is the trivial case `helm upgrade --install` against a name that does not exist yet has no previous revision, so there is nothing to carry forward or reset; the reuse flags are inert and the values are the chart's defaults plus whatever you pass. From the second upgrade onwards, the rule above applies.
- Does that default carry the old chart version's defaults forward as well?No. Only the release's user-supplied values are copied — the overrides someone passed on the previous command. Chart defaults are always read fresh from the chart being installed now, so a default that changed in the new chart version does take effect. That is exactly the difference from `--reuse-values`, which folds the old chart's defaults into the values map as if you had set them by hand.
- You pass a values file that is missing one key you set last time. What happens to that key?It falls back to the chart's default, because the file you passed is the entire override set and the previous overrides were discarded. If the chart defines no default for it, the template sees an empty value and may render nothing or fail a `required` call. This is the intended declarative behaviour: the file fully describes the release.
- Does `helm upgrade --install` behave differently on the very first run?Yes, trivially. There is no previous release, so there is nothing to carry forward or reset and the reuse flags do nothing. Values are the chart's `values.yaml` plus whatever the command passes. From the second upgrade on, the normal conditional rule applies.
saying these in an interview costs you the question
- Saying helm upgrade always reuses the previous release's values
- Saying helm upgrade always resets to the chart's defaults
- Thinking --set adds to the stored overrides instead of replacing them
- Believing the default carries the old chart version's defaults forward
- Expecting an error or warning when overrides are dropped
- Assuming the release's values live on the rendered objects