Helm 4.3 vs Helm 3.22: Migrating Before Helm 3 EOL
Last Updated: September 24, 2026
In September 2026 the Helm project shipped two releases on the same train. Helm 4.3.0 is the latest feature release of the Helm 4 line. Helm 3.22.0 is the last Helm 3 minor that will ever exist, and its only new content is a Kubernetes client library bump. From now until February 10, 2027, Helm 3 receives security patches on demand and nothing else. After that date it receives nothing at all. So the question of helm 4.3 vs helm 3 is no longer about whether the new major is ready. It is about how much of your delivery pipeline silently depends on Helm 3 behaviour, and whether you find out in a planned migration or in an incident. This guide compares the two lines flag by flag and mechanism by mechanism, explains what server-side apply actually changes for existing releases, shows how to port post-renderers to plugins, and lays out a staged migration for CI and GitOps fleets.
What this covers: the support timeline, the apply-engine change and its latch rule, the renamed and re-typed flags, what 4.3 adds on top of 4.0, a GitOps-aware migration runbook, and the failure modes that bite in production.
Context and Background
Helm has been the default package manager for Kubernetes since before most clusters ran production traffic. Helm 3, released in 2019, removed the in-cluster Tiller server and stored release state as Kubernetes Secrets in the release namespace. That design held for six years. It also accumulated debt: a plugin system that was really just “run an executable with some environment variables”, a readiness check that understood only a handful of built-in resource kinds, and a client-side patching engine that predates server-side apply.
Helm 4.0.0 shipped on November 12, 2025, at KubeCon North America. The Helm 4 release announcement framed it as a modernization release rather than a rewrite of the chart format. Charts that deploy with Helm 3 “should be deployable by Helm 4”, in the maintainers’ words, and Helm 4 can manage existing Helm 3 releases without a migration step. Helm 4.2 followed in May 2026, and 4.3.0 in September 2026.
The original Helm 3 support plan, published with the 4.0 release, promised bug fixes until July 8, 2026 and security fixes until November 11, 2026. On June 2, 2026, the maintainers published a revised plan in the Helm 3 end-of-life post. Bug fixes continued up to the final feature release on the September 9 release train. That final release, 3.22, was limited to Kubernetes client library updates, with no other features backported. Security support was extended by three months to February 10, 2027. The policy itself is governed by HIP-0012, the Helm Improvement Proposal that defines how an old major is maintained.
If you have read our Argo CD vs Flux GitOps decision record, you already know that neither controller is a thin wrapper around the Helm CLI. That matters here, because the Helm major your pipeline uses is not always the Helm binary on your laptop. It is often a Go library vendored inside a controller you did not build.
Helm 4.3 vs Helm 3.22: What Actually Changed Under the Hood
Helm 4.3 differs from Helm 3.22 in three load-bearing ways. New releases are applied with Kubernetes server-side apply instead of a client-side three-way merge. Post-renderers are typed plugins invoked by name, not executables invoked by path. And readiness waiting uses kstatus with selectable strategies. Charts themselves are largely unchanged.
The easiest way to reason about the migration is to separate what is visible from what is mechanical. The visible changes are flag names and one argument type. The mechanical changes are how Helm talks to the API server, how it decides a release is healthy, and how it extends itself. Most migration pain comes from the second group, because it surfaces only at runtime.

Figure 1: The Helm 3 to Helm 4 timeline, from the 4.0 release to the end of Helm 3 security support on February 10, 2027.
The timeline shows why the window is shorter than it looks. The 4.3.1 and 3.22.1 patches are scheduled for October 14, 2026, and 4.4.0 for January 13, 2027. That leaves roughly four weeks between the 4.4 release and the Helm 3 security cutoff. If your policy is “never adopt a .0 minor in production”, you should plan to land on 4.3.x, not wait for 4.4.
The apply engine: three-way merge versus server-side apply
Helm 3 computes changes on the client. For each resource it holds three documents: the manifest recorded in the previous release, the newly rendered manifest, and the live object fetched from the cluster. It diffs them and sends a patch. For built-in kinds that is a strategic merge patch; for custom resources it falls back to a JSON merge patch because the API server has no merge-key schema for them. The strength of this model is predictability for Helm-only resources. Its weakness is that Helm has no record of which fields other actors own. If an operator, an admission webhook, or a kubectl edit changed a field, Helm either tramples it or leaves drift, depending on whether that field appears in the chart.
Server-side apply (SSA) moves that bookkeeping into the API server. Each writer is a named field manager, and the server records field ownership in each object’s managedFields. When Helm applies a manifest with SSA, the server merges it, updates ownership, and rejects the request with a conflict if Helm tries to set a field another manager owns with a different value. Helm 4 exposes that choice through --server-side, which accepts true, false, or auto, and a new --force-conflicts flag that tells the server to take ownership despite conflicts.
This is a genuine improvement for clusters where Helm is not the only writer. It is also a new failure class. A three-way merge almost never fails outright; it just produces a surprising result. SSA fails loudly, at apply time, with a conflict message naming the other manager. For a pipeline that was silently fighting an operator for years, the first Helm 4 upgrade may be the first time anyone hears about it.
Istio’s 1.30 release is a real-world example. Its release notes list support for Helm v4 server-side apply alongside a fix for webhook failurePolicy field ownership during upgrades. That fix is exactly the shape of problem SSA surfaces: a field set by the chart, later rewritten by another controller, now contested under explicit ownership rules. If a project as heavily used as Istio needed chart-level changes, assume your in-house charts that touch webhooks, CRDs, or HPA-managed replica counts will need a look.
The latch rule: why your fleet will run both engines
The Helm 4 overview is precise about defaults. New releases get server-side apply. Upgrades and rollbacks follow the apply method of the previous release. The docs call this latching. Every release created by Helm 3 therefore continues with client-side apply after you switch binaries, unless you set --server-side explicitly. The CLI encodes it as --server-side=auto, which is the default.

Figure 2: How Helm 4 chooses between server-side apply and client-side three-way merge for each operation.
The decision flow has a consequence that the upstream docs do not spell out, so treat this as analysis. After migration, a single cluster will host two populations of releases. Old releases created under Helm 3 keep the client-side engine. Anything installed fresh after cutover uses SSA. Those two populations fail differently, drift differently, and respond differently to the same chart change. Your runbooks and alerting need to know which population a release belongs to.
The latch is the right default. Flipping an old release to SSA changes field ownership on every object it manages, and that should be a deliberate, per-release decision. But “the right default” is not “no decision”. The migration plan later in this article includes an explicit step to choose an SSA policy per release rather than inheriting whatever the latch gives you.
Readiness: kstatus and wait strategies
Helm 3’s --wait was a boolean. When set, Helm polled a fixed set of kinds using hand-written readiness rules: Pods, PVCs, Services, and a minimum number of ready Pods for Deployments, StatefulSets and ReplicaSets, plus Jobs when --wait-for-jobs was also set. Custom resources were effectively invisible to it.
Helm 4 integrates kstatus, the status library from the Kubernetes cli-utils project, under HIP-0022. kstatus computes a normalized status such as Current, InProgress, or Failed from standard conditions and generation fields, which lets it reason about any resource that follows common conventions, including many CRDs. The flag is now typed: --wait takes a strategy of watcher, hookOnly, or legacy. Passing --wait alone selects watcher. Omitting it entirely means hookOnly, which waits only on hooks.
Helm 4.3 tightens this engine. It lowers the watcher’s resync period from one hour to three minutes and computes status concurrently to prevent multi-minute delays. If you tried Helm 4.0 or 4.1 against a large release and saw waits hang far longer than the resources took to become ready, those two changes target that symptom. The legacy strategy exists for teams that need Helm 3’s exact readiness semantics during a transition.
Deeper Analysis: Flags, Plugins, and What 4.3 Adds
This section is the working reference. Start with the table, then read the plugin and 4.3 subsections, because those contain the breakages that grep will not find.
Flag and behaviour comparison
| Area | Helm 3.22 | Helm 4.3 | Migration action |
|---|---|---|---|
| Rollback on failed upgrade | --atomic (implies wait) |
--rollback-on-failure; defaults --wait to watcher |
Rename; --atomic still works with a deprecation warning |
| Replace on conflict | --force |
--force-replace |
Rename; old flag warns |
| Apply engine | Client-side three-way merge only | --server-side=auto (default), true, false; --force-conflicts |
Decide per release |
| Waiting | --wait boolean |
--wait=watcher, hookOnly (default when omitted), legacy |
Audit scripts that assumed boolean semantics |
| Post-renderer | --post-renderer /path/to/exe (plus --post-renderer-args) |
--post-renderer <plugin-name>; --post-renderer-args unchanged |
Package as postrenderer/v1 plugin |
| Registry login | Accepted full URLs | Domain name only | Strip scheme and path in CI |
| Plugin model | Unversioned plugin.yaml, subprocess |
Versioned apiVersion: v1, typed plugins, subprocess or Wasm runtime |
Existing plugins keep working; migrate schema when convenient |
| Values input | One document per file | Multi-document values files | Optional |
| Uninstall safety | Deletes resources in the release manifest | Verifies ownership before deleting (4.3) | Check adopted resources |
| Rollback audit | No reason field | helm rollback --description (4.3, max 256 runes) |
Adopt in runbooks |
| Stdout hygiene | Mixed | Registry messages to stderr in template/show (4.3 fix) |
Re-test stdout parsers |
| Chart API | apiVersion: v2 |
v2 unchanged; Charts v3 experimental behind HELM_EXPERIMENTAL_CHART_V3 |
Do not adopt v3 charts in production |
| Support | Security fixes only until Feb 10, 2027 | Active; 4.4.0 scheduled Jan 13, 2027 | Migrate |
Two rows deserve emphasis. First, --rollback-on-failure is not a pure rename. In Helm 4 it defaults the wait strategy to watcher, so the readiness engine that decides whether to roll back is kstatus, not Helm 3’s hand-written checks. A release that “passed” under --atomic because Helm 3 ignored a stuck custom resource may now fail and roll back. That is arguably correct, but it is a behaviour change hiding behind a flag rename.
Second, the --dry-run flag is now explicitly typed as none (the default), client, or server. Helm 3.22 already accepted client and server, and there a bare --dry-run meant client. In Helm 4 a bare --dry-run no longer maps to client in the flag definition, and many older scripts still pass it bare. Check what your scripts actually get, and always pass an explicit value.
A minimal CI diff for a typical upgrade step looks like this:
# Helm 3.22
helm upgrade --install payments ./charts/payments \
--namespace payments --atomic --timeout 10m \
--post-renderer ./hack/kustomize-wrap.sh \
-f values/prod.yaml
# Helm 4.3
helm upgrade --install payments ./charts/payments \
--namespace payments --rollback-on-failure --timeout 10m \
--post-renderer kustomize-wrap \
--server-side=auto \
-f values/prod.yaml
Making --server-side=auto explicit changes nothing functionally. It documents intent in the pipeline, so the next reviewer knows the latch rule was a choice.
Post-renderers become plugins
In Helm 3, --post-renderer took a path to any executable. Helm piped rendered YAML to its stdin and read patched YAML from stdout. Teams used it mostly to wrap kustomize, inject sidecars, or stamp labels. In Helm 4 the same flag takes the name of an installed plugin of type postrenderer/v1. Passing a path no longer works.

Figure 3: Helm 3 invokes a post-renderer by executable path; Helm 4 resolves a typed plugin by name and runs it in a subprocess or Wasm runtime.
The upstream tutorial shows the minimal shape. A plugin directory holds a manifest and the script it runs:
# plugin.yaml
apiVersion: v1
type: postrenderer/v1
name: kustomize-wrap
version: 0.1.0
runtime: subprocess
runtimeConfig:
platformCommand:
- command: ${HELM_PLUGIN_DIR}/kustomize-wrap.sh
helm plugin install ./plugins/kustomize-wrap # local dir installs in dev mode, no provenance check
helm plugin list # TYPE column should read postrenderer/v1
helm template ./charts/payments --post-renderer kustomize-wrap
The script body usually does not change at all. What changes is packaging and distribution. In CI, the plugin must be installed into the runner’s HELM_PLUGINS directory before the upgrade step runs. For reproducible builds, package the plugin with helm plugin package and install a pinned artifact, rather than installing from a working-tree directory. Local directory installs run in development mode and skip provenance checks, which is fine on a laptop and a poor habit on a shared runner. --post-renderer-args, which accepts multiple values, works as it did in Helm 3, so arguments you already pass that way carry over unchanged.
The subprocess runtime is the easy port. The optional WebAssembly runtime, defined in HIP-0026, is the long-term reason for the redesign: a Wasm plugin runs sandboxed rather than as an arbitrary host process. The upstream tutorial for Wasm post-renderers was still marked as a to-do when this article was written, so treat Wasm as an evaluation track, not a migration requirement.
What Helm 4.3 adds on top of 4.0
If you evaluated Helm 4.0 in late 2025 and parked it, 4.3 is worth a fresh look. The notable changes from the GitHub release notes fall into three groups.
Safety and correctness. Uninstall now verifies ownership before deleting resources. If a resource in the release manifest has been adopted by another owner, Helm 4.3 will not blindly delete it. A long-standing bug where values files ending exactly on a 4096-byte boundary were dropped is fixed. And a regression that printed registry messages to stdout during helm template and helm show is fixed, so they go to stderr again. That last one matters to any pipeline that pipes helm template into kubectl apply -f - or into a policy scanner.
Operability. helm rollback --description records a reason for the rollback, capped at 256 characters counted in runes. helm history makes the rollback-revision column opt-in via --show-rollback-revision. Debug logging now reports when a lookup call returns empty, which is the single most common source of “works in install, breaks in template” confusion. Chart authors also get new duration template functions for working with time values. The watcher improvements covered earlier reduce wait latency.
Supply chain and reproducibility. Chart archives honour SOURCE_DATE_EPOCH, modification timestamps are normalized to UTC, and Chart.lock handling is more reproducible. Together these move Helm toward byte-identical archives from the same chart source, which is what makes digest pinning meaningful. Verify reproducibility in your own pipeline rather than assuming it. Helm 4 already supported installing charts by OCI digest; reproducible archives are the other half of that story. Provenance verification also accepts GnuPG keybox pubring.kbx keyrings. The Kubernetes client libraries move to 0.37.0, aligned with Kubernetes 1.37, which we covered in our Kubernetes 1.37 DRA and GPU device plugin guide.
Two changelog items are worth noticing even though they are internal. Deprecated internal/chart/v3/ code was removed, and the per-file decompression size limit was removed. Neither changes chart authoring, but the second one shifts a defensive limit off Helm. If you ingest charts from untrusted sources, keep size limits in your registry or admission layer.
A Staged Migration Plan for CI and GitOps
The official checklist is five lines: test charts on Helm 4 in non-production, update CI for renamed flags, migrate post-renderers to plugins, test OCI login with domain-only syntax, then upgrade. It is correct, and it is incomplete for any organization running GitOps. Here is the thesis of this article: the risk in a Helm 4 migration is not in your charts but in the ownership boundaries around them. That means who applies the manifests, which engine applies them, and which other managers write to the same fields. The plan below is ordered around those boundaries.

Figure 4: A staged Helm 4 migration runbook that treats GitOps controller compatibility and SSA policy as explicit gates before production cutover.
Stage 1: inventory what actually calls Helm
List every place Helm runs. That includes CI jobs, developer scripts, Makefiles, platform tooling, and, critically, controllers. For each, record the Helm major, which flags are used, whether a post-renderer is involved, and whether stdout is parsed. A simple search catches most of it:
grep -rnE -- '--atomic|--force( |$)|--post-renderer|registry login|--wait( |$)' \
.github/ .gitlab-ci.yml ci/ scripts/ Makefile
helm list -A -o json | jq -r '.[] | "\(.namespace)/\(.name) \(.chart) \(.app_version)"'
The second command gives you the release population that will latch to client-side apply after cutover. Save it. You will want that list when you decide SSA policy.
Stage 2: mechanical CI changes
Rename --atomic to --rollback-on-failure and --force to --force-replace. The old names keep working with deprecation warnings, but a warning in CI logs is noise that hides real warnings. The project has not published a removal date for the old names; Helm 5 is the likely point, but that is an inference. Change helm registry login https://registry.example.com/v2/ to helm registry login registry.example.com. Replace bare --wait with an explicit strategy. Pin the Helm binary by version and checksum in the runner image rather than using a “latest” install script.
Stage 3: port post-renderers and plugins
Convert each post-renderer to a postrenderer/v1 plugin, package it, and install it from a pinned artifact in the runner image. Existing Helm 3 CLI plugins keep working, including those using the subprocess runtime. The only legacy element is the unversioned plugin.yaml schema. Migrate that schema when you next touch the plugin, not as a gate.
Stage 4: prove chart equivalence
Render every chart with both binaries and diff the output. Rendering is not where Helm 4 changes much, so a clean diff is expected and fast to confirm:
for env in dev staging prod; do
helm3 template app ./charts/app -f values/$env.yaml > /tmp/h3-$env.yaml 2>/dev/null
helm template app ./charts/app -f values/$env.yaml > /tmp/h4-$env.yaml 2>/dev/null
diff -u /tmp/h3-$env.yaml /tmp/h4-$env.yaml || echo "DIFF in $env"
done
A diff here usually points to a post-renderer that did not port cleanly, a values file affected by the 4096-byte bug on older 4.x builds, or a template relying on lookup behaviour. The new debug log for empty lookup results helps with the last case.
Stage 5: the GitOps gate
This is the step the official checklist does not have. Argo CD and Flux both embed Helm, but differently, and that changes what “migrating to Helm 4” means for each. The architectures are covered in depth in our Argo CD and Flux GitOps tutorial for industrial fleets.
Argo CD uses Helm to render templates, then applies the output with its own sync engine. For Argo CD, Helm’s apply-engine change is largely irrelevant; Argo CD’s own sync options decide client-side versus server-side apply. What matters is which Helm library version Argo CD vendors for rendering, because that governs template functions, values parsing, and OCI behaviour.
Flux’s helm-controller uses the Helm SDK to perform real installs and upgrades, and it writes Helm release records. For Flux, the SDK major determines the apply engine, the wait behaviour, and the latch rule for every HelmRelease it manages.
I have not verified which Helm major the current Argo CD and Flux releases vendor, and it may change between minor versions. Treat it as a checkpoint: read your controller’s release notes or go.mod before cutover, and pin the controller version until you have. Do not upgrade the CLI in CI and assume the controller followed.
Stage 6: canary, then SSA policy, then production
Run Helm 4 against one non-critical cluster first. Upgrade existing releases, which will latch to client-side apply, and install at least one new release, which will use SSA. Watch for conflicts. Then decide policy per release:
- Leave latched (client-side). Right for stable releases with no other writers. Zero behaviour change.
- Opt in to SSA. Right for releases that share objects with operators, HPAs, or webhooks. Run
helm upgrade --server-side=trueonce in a maintenance window, resolve conflicts in the chart, and use--force-conflictsonly when you have confirmed Helm should own the contested field. - Pin to client-side. Use
--server-side=falsefor new installs that must behave exactly like their Helm 3 siblings, for example during a multi-cluster rollout where half the fleet is still on Helm 3 tooling.
For multi-cluster estates, the ordering interacts with how you manage clusters. Our Kubernetes multi-cluster management guide with Cluster API covers staged rollout rings; apply the same rings to the Helm binary and controller versions.
A rough effort model
The following numbers are my estimates from the shape of the work, not measured data. A team with 20 to 50 releases, one CI system, no custom post-renderers, and Argo CD rendering can expect stages 1 through 4 to take two or three engineer-days. Each custom post-renderer adds roughly half a day for packaging and runner-image changes. A Flux-managed fleet with operators writing into Helm-managed objects is a different class: budget a week or more, dominated by stage 6 conflict resolution, because every conflict is a real ownership question someone has to answer.
Trade-offs, Gotchas, and What Goes Wrong
Server-side apply is not free. It trades silent drift for loud conflicts. That is the right trade for shared objects and a net cost for simple, Helm-only releases, where client-side merge rarely surprised anyone. SSA also makes managedFields part of your debugging surface; engineers who never read them will need to learn.
The latch rule creates a mixed fleet by design. Two releases of the same chart can behave differently because one was installed before cutover and one after. Incident responders need to check which engine a release uses before reasoning about drift. Record the chosen policy in release labels (helm upgrade -l apply=ssa) so it is visible without archaeology.
Here are specific failure modes to expect, labelled as analysis derived from the documented behaviour:
- Field-manager conflicts on new releases. A fresh install with SSA collides with fields that kubectl, an operator, or a GitOps controller already owns on pre-existing objects, especially when adopting resources with
--take-ownership. - Stricter rollbacks.
--rollback-on-failurewaits with kstatus. Releases that previously passed with a stuck CRD may now roll back. Check timeouts, and do not silently switch to--wait=legacyto make the pipeline green. - Stdout parsers. Pipelines that parse
helm templateoutput were exposed to a registry-message regression that 4.3 fixes. If you pinned an earlier 4.x, upgrade or filter stderr explicitly. - Uninstall refusing to delete. Ownership verification can leave resources behind that another owner adopted. That is safer, but cleanup jobs that assumed uninstall removes everything will leave orphans.
- Registry login in CI. A full URL that worked for years now fails. It is trivial to fix and easy to miss in rarely run pipelines, such as disaster-recovery jobs.
- Charts v3 temptation. Charts v3 is experimental behind
HELM_EXPERIMENTAL_CHART_V3. Its maturity in 4.3 is not something I could confirm as stable. Do not ship v3-format charts to production.
The anti-pattern to avoid is “big-bang with --force-conflicts everywhere”. It turns a useful signal into a destructive one: Helm will seize fields from operators that legitimately own them, and the operator will fight back on its next reconcile.
Practical Recommendations
Treat February 10, 2027 as a hard wall, not a soft target. After that date a Helm 3 CVE means running unpatched software in the component that has write access to every namespace you deploy into. Aim to finish production cutover by mid-January, which leaves time to absorb the 4.4.0 release or stay on 4.3.x deliberately.
Land on Helm 4.3.x, and take the 4.3.1 patch scheduled for October 14, 2026, once it ships. The 4.3 line carries the watcher latency fixes, uninstall ownership checks, and reproducible archives, all of which make the migration safer than 4.0 would have been. Keep a 3.22.x binary available during the transition for side-by-side rendering and emergency rollbacks of tooling, and remove it after cutover.
Make the SSA decision explicit per release. The latch default is safe, but a fleet that never decides ends up with engine choice determined by install date. Use SSA for anything that shares objects with other controllers, and keep client-side apply for simple, Helm-only releases until you have a reason to change.
Checklist:
- [ ] Inventory every Helm caller, including controllers, with the Helm major each uses.
- [ ] Rename
--atomicand--force; set explicit--waitand--dry-runvalues. - [ ] Change registry login to domain-only in all pipelines, including rarely run ones.
- [ ] Package post-renderers as
postrenderer/v1plugins, installed from pinned artifacts. - [ ] Diff
helm templateoutput from 3.22 and 4.3 for every chart and environment. - [ ] Confirm the Helm major vendored by Argo CD or Flux before upgrading them.
- [ ] Canary on one cluster; install one fresh release to exercise SSA.
- [ ] Record SSA policy per release in labels; ban blanket
--force-conflicts. - [ ] Complete production cutover before February 10, 2027.
Frequently Asked Questions
When does Helm 3 reach end of life?
Helm 3 bug fixes ended with the final feature release, 3.22, on the September 2026 release train. Helm 3 security fixes continue on demand until February 10, 2027. That date is three months later than the original November 11, 2026 plan. During the security-only window there are no features, no Kubernetes client library updates, and no bug fixes. After February 10, 2027, there will be no Helm 3 releases of any kind, so any vulnerability discovered after that date stays unpatched.
Do I need to migrate existing Helm 3 releases to use Helm 4?
No explicit migration step is required. Helm 4 reads and manages releases created by Helm 3 directly. You install the new binary and run upgrades as usual. The one behavioural nuance is the apply engine. Existing releases latch to the client-side apply method they were created with, so they keep Helm 3 patching behaviour until you opt in with --server-side=true. Test in non-production first, because readiness checks and flag semantics have still changed around those releases.
What replaced –atomic in Helm 4?
--atomic is renamed to --rollback-on-failure, and --force is renamed to --force-replace. The old names still work in Helm 4 but emit deprecation warnings, so update scripts now. The rename is not purely cosmetic. In Helm 4, --rollback-on-failure defaults the wait strategy to watcher, which uses kstatus to judge readiness. A release that passed Helm 3’s narrower checks may now fail and roll back if a resource such as a custom resource never reaches a ready state.
Is server-side apply the default in Helm 4?
Server-side apply is the default for new releases only. Upgrades and rollbacks follow the previous revision’s apply method, which the Helm docs call latching. The --server-side flag accepts true, false, or auto, and auto is the default. When SSA meets a field another manager owns with a different value, the API server reports a conflict. You can override with --force-conflicts, but only after confirming Helm should own that field, because the other controller will likely reassert it.
How do I migrate a Helm post-renderer to Helm 4?
Wrap the existing script in a plugin directory with a plugin.yaml declaring apiVersion: v1, type: postrenderer/v1, a name, a version, runtime: subprocess, and the command to run. Install it with helm plugin install, confirm it with helm plugin list, and pass its name to --post-renderer instead of a path. Extra arguments go through --post-renderer-args. In CI, install the plugin from a packaged, pinned artifact so every runner uses the same version.
Will my Helm 3 charts work with Helm 4.3?
In most cases, yes. The maintainers state that charts deployable with Helm 3 should be deployable by Helm 4, and apiVersion: v2 charts continue to work unchanged. Charts v3 is a separate, experimental format behind an environment variable and is not needed for migration. Verify by rendering each chart with both 3.22 and 4.3 and diffing the output. Differences usually come from post-renderers, lookup calls, or values-file edge cases rather than from the template engine itself.
Further Reading
- Argo CD vs Flux: a GitOps decision record — how the two controllers differ in rendering, applying, and reconciling Helm charts.
- Argo CD and Flux GitOps for industrial fleets: a 2026 tutorial — hands-on setup of both controllers across many edge clusters.
- Kubernetes 1.37 DRA and GPU device plugins — the Kubernetes release whose client libraries Helm 4.3 tracks.
- Kubernetes multi-cluster management with Cluster API — rollout rings and fleet patterns that apply to staged Helm upgrades.
- Helm v4.3.0 release notes on GitHub — the primary source for every 4.3 change listed above.
- Helm 4 Overview — official breaking changes, the SSA latch rule, and the upgrade checklist.
By Riju — about
