Helm 3 End of Security Support: Why Kubernetes 1.38 Lands First

Helm 3 security patches end February 10, 2027, but bug fixes stopped in September and Kubernetes 1.38 ships in December. Three Helm pages still give three different dates.

By VVV Ops ·

Your Helm line item probably reads "migrate before February 2027" and sits in next quarter's column. Two things are wrong with that. Helm 3 end of security support does land on February 10th, 2027, but bug fixes stopped in September 2026, so you are already running a binary that gets touched only when someone reports a CVE. Kubernetes 1.38 is scheduled for December 16th, 2026, which puts your clusters past the newest Kubernetes that Helm 3 was ever compiled against while the migration is still parked. The date on the board is not the date that bites.

Three official dates, and Helm still publishes all three

Every team we have asked about this quoted a different deadline, and every one of them could point at a Helm page to prove it. All three pages are still live.

| Source | Bug fixes end | Security fixes end | |---|---|---| | HIP-0012 | "6-8 months following the release of Helm 4" | One year from Helm 4 availability, with end of life "estimated" July 2026 | | Helm 4 release announcement, November 2025 | July 8th 2026 | November 11th 2026 | | Helm 3 End of Life, current | September 9th 2026 | February 10th 2027 |

The bottom row is the one in force. The end-of-life post says security fixes end "February 10th, 2027 (extended from November 2026)", and that after that date "no further Helm 3 releases of any kind will be made".

The November 11th date did not disappear, which is where the confusion comes from. It is now a scheduled patch date. The Helm releases page lists 3.22.2 and 4.3.2 for November 11th, 2026. A date that used to mean end of life now means a routine patch, and plenty of migration guides written in the first half of this year never got updated.

If your plan cites July 2026 or November 2026, it was built from a superseded page. Rebuild it from the end-of-life post.

You are already past the bug-fix line

Helm 3.22.0 shipped on September 10th, 2026 and its own release notes say there will be no further Helm 3 minor releases. The notes describe it as mainly dependency updates, with the Kubernetes client libraries moved to the 1.37 line, and the end-of-life post is explicit that "no other new features will be backported".

What that leaves is narrow. Bug fixes ran "up to the final feature release, September 9th, 2026". From then until February, "only security patches will be released (on demand / as needed)" and "no bug fixes will otherwise be applied". Version 3.22.1 arrived on October 15th, 2026 on that basis.

So a Helm 3 bug you hit today is yours to work around. There is no upstream fix coming for a templating edge case, a flaky --wait, or a rollback that leaves a release stuck. We have stopped filing Helm 3 issues for clients and started counting those workarounds as migration cost, because that is what they are.

Kubernetes 1.38 is the deadline nobody put on the board

Helm's version skew policy is the part of this that catches people. Helm is compiled against a particular minor version of Kubernetes. The policy says that as of Helm 4, Helm "is assumed to be compatible with n-3 versions of Kubernetes it was compiled against", that using Helm against a newer Kubernetes than it was compiled against is not recommended, and that Helm "does not make any forward compatibility guarantees". The compatibility table on that page starts at Helm 4.0.x. There is no Helm 3 row left in it.

Today there is no gap. Both current binaries pin the same Kubernetes libraries:

# Both lines print v0.37.1 right now. That is the point: the gap opens later.
for v in v3.22.1 v4.3.1; do
  printf '%s ' "$v"
  curl -sS "https://raw.githubusercontent.com/helm/helm/refs/tags/$v/go.mod" \
    | awk '/k8s.io\/client-go/ {print $2}'
done

Both tags carry k8s.io/client-go v0.37.1, which is Kubernetes 1.37. The 3.22 line moved Helm 3 onto those libraries, and no Helm 3 release will move them again.

Now put the Kubernetes calendar next to it. The v1.38 schedule proposes code freeze on November 17th and v1.38.0 on December 16th, 2026. Helm 4.4.0 is scheduled for January 13th, 2027, which is where a 1.38 client bump would land. Helm 3 does not get that release.

The practical consequence: if your upgrade plan has any cluster on 1.38 in the first quarter of 2027, Helm 3 is running against an unsupported Kubernetes before February 10th, with no forward compatibility promise behind it. Teams that sequenced the Kubernetes upgrade first and the Helm migration second have the order backwards. Do Helm first. It takes less time and it is a precondition for the other one.

This is the same failure we wrote about in the containerd 1.7 migration, where the widely quoted deadline belonged to different code than the one that actually stopped working, and in Kubernetes extended support cost, where the date on the invoice was not the date anyone was watching.

What the migration guides tell you to fear, and what actually breaks

Read five Helm 4 migration posts and you will come away expecting a hard cutover: server-side apply rewriting field ownership, plugins dead, charts needing a rewrite. Helm's own overview says otherwise on all three.

Server-side apply is opt-in for anything you already run. New installs default to server-side apply, but on upgrade and rollback "Helm will by default follow the previous apply method of the release", and "all releases created by Helm 3 will default to using client-side apply after upgrading to Helm 4". Your existing releases keep doing exactly what they did. You move them with --server-side when you choose to.

Plugins are mostly fine. The overview states that "existing plugins work as before". The break is narrower: post-renderers became a plugin type, so the flag no longer takes an arbitrary executable and wants a plugin name instead. If you pipe manifests through a shell script today, that script needs packaging.

Charts do not need a rewrite. "V2 charts continue to work unchanged." There is a chart apiVersion v3, and it is experimental behind the HELM_EXPERIMENTAL_CHART_V3 environment variable. Ignore it for this migration.

What that leaves is a tooling migration, not a cluster migration. The damage is in your pipelines and in any Go code that imports Helm. Those are the two places to spend the budget, and neither of them touches a running workload.

The CI edits, in the order we make them

These come from the Helm 4 changelog and the overview. Flag renames keep the old name with a deprecation warning, with one caveat in the table.

| What your pipeline runs | Helm 4 behaviour | Fix | |---|---|---| | helm version --client --short | --client was removed (changelog #31301) | helm version --short | | helm repo add ... --no-update | Flag removed (#13494) | Drop the flag | | helm lint with no path | Implicit current directory removed (#31294) | helm lint . | | helm upgrade --atomic | Renamed to --rollback-on-failure, old name warns | Rename it, and read the caveat below | | helm upgrade --force | Renamed to --force-replace, old name warns | Rename it | | helm test --create-pods | Removed (#31023) | Drop the flag | | --post-renderer /path/to/script | Expects a plugin name | Package the script as a plugin |

The caveat on --atomic: a later patch, #31901, had to "restore (deprecated) --atomic flag on install command for backwards compatibility". The alias was not uniform across subcommands on the first try. Do not assume the deprecated name survives everywhere. Run the exact commands your pipelines run against a 4.3.1 binary and read the warnings.

helm version --client --short is the one that bites hardest, because it is the line a lot of CI images run to assert a Helm version before doing anything else. It fails first and it fails loudly, which at least makes it cheap to find.

Charts and the SDK are two different migrations

If you have Go code that imports Helm, that is a separate piece of work with its own risk, and it is worth checking before you commit to a date. The changelog lists the moves:

  • The module path changed from helm.sh/helm/v3 to helm.sh/helm/v4 (#13573)
  • pkg/chart became pkg/chart/v2 (#30586)
  • pkg/release became pkg/release/v1 (#30589)
  • chartutil moved to chart/util (#30567)
  • pkg/releaseutil became pkg/release/util (#30580)
  • pkg/plugin moved to internal/plugin (#31142)

Most of those are mechanical. The last one is not. A move into internal/ means the package is no longer importable from outside the Helm module, so code that built on pkg/plugin has no public replacement to point at. Check for that import first, before you estimate anything else, because it is the one that can turn a rename exercise into a redesign.

Teams running a custom controller or an internal developer platform that wraps Helm are the ones who need to look. If your only Helm usage is the CLI in a pipeline, skip this section.

A cutover we would actually run

Two weeks of elapsed time for a fleet, most of it waiting rather than working.

  1. Inventory what you have. On every runner image, helm version --short. In the cluster, get the real list of releases:
helm list --all-namespaces -o json \
  | jq -r '.[] | [.namespace, .name, .chart, .app_version] | @tsv'
  1. Install 4.3.1 next to 3.22.1 in your CI image as a second binary. Do not replace anything yet. Both can read the same release state.
  2. Fix the flags from the table above, one pull request per repository. This is the bulk of the work and it is boring.
  3. Run --dry-run upgrades with the Helm 4 binary against every release and diff the rendered output against what Helm 3 produces. Differences here are the only real surprises you will get, and they are usually whitespace.
  4. Swap the default binary. Keep 3.22.1 in the image until your clusters are on 1.38, as a rollback option that still has a supported client.
  5. Decide on --server-side per release, after the cutover, when nothing else is moving.

Step 4 is the one teams skip and the one that pays for itself. Step 6 is the one teams try to do at the same time as step 5, which turns a reversible change into an irreversible one.

When to Get Help

Most teams can run this themselves in two weeks. The ones that call us have a specific shape of problem: a few hundred releases across clusters on different Kubernetes minors, a wrapper service importing pkg/plugin, or a Kubernetes 1.38 upgrade already booked for January that now has a Helm dependency in front of it. Untangling the order of those two migrations is where the time goes, and getting it wrong means running an unsupported client against a brand new control plane.

If that is your situation, or your current plan is built on the November 2026 date, get in touch and we will go through your release inventory and sequence the two upgrades with you.

Tags: helm 3 end of security support, helm 4 migration, kubernetes deployment automation, kubernetes consulting, devops automation services, infrastructure as code