skip to content

A Helm 4 upgrade fails on an apply conflict with another field manager. What does --force-conflicts do, and when is it the wrong fix?

level: seniorimportance: should knowfreq 44%

answer

  1. The API server refused the write, not Helm
  2. Someone else already owns those fields
  3. The override transfers ownership, per invocation
  4. Ask whether that owner will write back
  5. A different flag entirely recreates the object

basics

~20 s

The conflict means another manager already owns the fields Helm is trying to set. --force-conflicts tells the API server to override that and hand ownership to Helm. It is wrong when the other owner is a controller that will immediately write the field back.

solid answer

~50 s

Under server-side apply the API server records which manager set each field, and it refuses a write that would take a field from someone else. Helm surfaces that refusal as a failed upgrade naming the competing manager and the field paths. `--force-conflicts` re-sends the same apply with the override set, so the API server transfers ownership of those fields to Helm. That is the right call when the other owner was a human — a one-off live edit that the chart should now govern. It is the wrong call when the other owner is a live controller, because forcing starts a loop where each side rewrites the field on every reconcile; the fix there is to stop templating that field in the chart. Note that `--force-conflicts` is not `--force-replace` (deprecated alias `--force`); the two are mutually exclusive.

code

bash · 8 lines
bash
# fails: another manager owns some of the fields this apply would set
helm upgrade fraud-scoring ./vendor-scoring-chart -n risk

# check whether a chart change clears it, without persisting a revision
helm upgrade fraud-scoring ./vendor-scoring-chart -n risk --dry-run=server

# take the remaining fields over on purpose, after checking the live values
helm upgrade fraud-scoring ./vendor-scoring-chart -n risk --force-conflicts

go deeper

for a junior

Know that a Helm 4 upgrade can fail because something else in the cluster already set the fields it wants, and that the error names who. Do not reach for a force flag before asking someone why the conflict exists.

for a middle

Explain the mechanism: server-side apply tracks per-field ownership, the API server refuses a write that would take a field, and --force-conflicts re-sends the apply with the override so ownership moves to Helm.

for a senior

Demonstrate the triage: read which fields and which manager, decide per field whether the chart or the other actor should own it, change the chart where the answer is the other actor, and force only what a human once edited.

for a principal

Own the ownership boundary itself — which fields charts are allowed to render when controllers also write them, how you keep force flags out of standing pipelines, and how teams record who owns a contested field before an incident makes it urgent.

This failure only exists on the server-side apply path, which is Helm 4's default for new releases. Under it, Helm sends the whole rendered object and the API server merges it, keeping a per-field record of which manager set what. When Helm's apply would change a field that a different manager owns, the server refuses the write and returns a conflict naming the competing manager and the offending field paths. Helm reports the upgrade as failed and the release is left for you to decide about. ## Read the conflict before you resolve it The error is information, not an obstacle. It tells you three things: which fields are contested, who else claims them, and — implicitly — that your chart and something else in the cluster both believe they define this object. Take a concrete case: a chart that wraps a vendor image and drives it from a values-generated config file, installed as a fraud-scoring release. Revision 35 fails on `spec.replicas`, owned by an autoscaling controller, and on an annotation owned by an ingress-side controller. Neither is a Helm bug; both are a design statement about ownership that nobody wrote down. ## What --force-conflicts actually does `--force-conflicts` re-sends the same server-side apply with the conflict override set. The API server stops refusing, applies Helm's values, and transfers ownership of those fields to Helm's field manager. Two properties matter. First, it is a per-invocation override, not a setting on the release: the next upgrade without the flag will hit the same conflict again if the other actor has taken the field back. Second, it is unconditional for that apply — you cannot force one field and leave another — so anyone reaching for it should already know every field it is going to seize. ## When forcing is right Forcing is the correct resolution when the competing owner is not going to compete again. The classic case is a human: somebody ran a live edit during an incident, the field now belongs to their client's manager, and the chart is the intended source of truth. Confirm the live value is not load-bearing — you are about to overwrite it with whatever the chart renders — and force. The same reasoning covers a decommissioned tool that once wrote to the object and is no longer running. ## When forcing is wrong Forcing is wrong when the other owner is alive and opinionated. If an autoscaling controller owns `spec.replicas`, forcing gives Helm the field for a moment and the controller takes it back on its next reconcile, so every upgrade conflicts, every force stomps the current scale, and the workload is briefly resized to the chart's default. The real fix is a chart change: stop rendering the field at all, or make it conditional so the chart yields to whoever should own it. That conversation — who owns this field, the chart or the controller — is what the interviewer is actually testing. Repeatedly forcing is how a team converts an explicit, useful error into a recurring production surprise. ## Do not confuse it with --force-replace Helm 4 also has `--force-replace`, whose deprecated alias is the bare `--force`. It is a completely different mechanism and Helm treats the two as mutually exclusive, so you cannot pass both. Reaching for `--force` because an upgrade failed, in the belief that it resolves apply conflicts, is one of the most common Helm 4 mistakes carried over from Helm 3 habits, and it asks for something far blunter than the flag you meant. ## Diagnosing without changing anything `--dry-run=server` sends the request to the API server for validation without persisting a revision, so you can see whether the conflict is still there after a chart change, without another failed release revision in the history. That is the loop to run: read the conflict, decide per field who should own it, change the chart for the fields that belong to somebody else, then force only the remainder — once, deliberately, with the current live values checked first. ## Why this did not happen before On the Helm 3 client-side path there was no ownership record, so the same situation produced no error at all: Helm computed a patch and either silently overwrote the other actor's value or silently kept it, depending on how the field was structured. Teams discovered the disagreement weeks later as drift. The Helm 4 behaviour is not a new problem; it is an old problem that now announces itself at the moment it happens, which is why the right response is usually a decision about the chart rather than a flag that suppresses the message.

  • The conflicting field is spec.replicas and an autoscaling controller owns it. What do you change?
    The chart, not the flag. Stop rendering `spec.replicas`, or render it only when autoscaling is disabled in values, so the object no longer claims a field another controller manages. Forcing would win the field for one apply and lose it again on the controller's next reconcile, resizing the workload to the chart's default each time and reproducing the conflict on every upgrade.
  • Does --force-conflicts stay in effect for later upgrades of that release?
    No. It is an override on that one invocation, not a property recorded on the release. Ownership does move to Helm's manager for the fields it seized, so the next upgrade may pass — but only until another actor writes those fields again, at which point the conflict returns. Persistent conflicts are a signal to change the chart rather than to add the flag to your pipeline permanently.
  • Can you pass --force-conflicts together with --force-replace?
    No — Helm treats them as mutually exclusive and rejects the combination. They solve different problems: one overrides field ownership within server-side apply, the other is Helm's separate replace path. The bare `--force` is a deprecated alias of `--force-replace`, so typing `--force` to fix a conflict asks for the wrong mechanism.

saying these in an interview costs you the question

  • Says --force resolves server-side apply conflicts
  • Adds --force-conflicts permanently to the pipeline
  • Believes the conflict is a Helm bug, not a real disagreement
  • Forces a field a live controller owns and expects it to stick
  • Thinks --force-conflicts and --force-replace can be combined
  • Never checks the live value before overwriting it

context