Skip to content

fix: retry Helm upgrade with Force when a patch is rejected - #138

Draft
bschimke95 wants to merge 2 commits into
fix/post-refresh-deprecated-kubelet-flagsfrom
fix/helm-upgrade-force-retry
Draft

bschimke95 wants to merge 2 commits into
fix/post-refresh-deprecated-kubelet-flagsfrom
fix/helm-upgrade-force-retry

Conversation

@bschimke95

@bschimke95 bschimke95 commented Oct 7, 2026 •

Copy link
Copy Markdown
Collaborator

Stacked on #137 (and #132).

Helm's 3-way merge patch for an upgrade can occasionally compute an update the API server rejects, e.g. cannot patch "coredns" with kind Service: Service "coredns" is invalid: spec.ports: Required value.

Change

  • On an upgrade patch failure, retry once with Force, which makes Helm delete and recreate the conflicting resource(s) instead of patching them — Helm's own documented recovery path for this class of failure.

@bschimke95
bschimke95 force-pushed the fix/helm-upgrade-force-retry branch from 3d72a63 to 93d3d00 Compare October 7, 2026 10:18
@bschimke95
bschimke95 force-pushed the fix/post-refresh-deprecated-kubelet-flags branch from 2c496e4 to 65d2334 Compare October 8, 2026 13:18
@bschimke95
bschimke95 force-pushed the fix/helm-upgrade-force-retry branch from 93d3d00 to 727a1a2 Compare October 8, 2026 13:21
@bschimke95
bschimke95 force-pushed the fix/post-refresh-deprecated-kubelet-flags branch from 65d2334 to bca54ed Compare October 8, 2026 13:44
@bschimke95
bschimke95 force-pushed the fix/helm-upgrade-force-retry branch from 727a1a2 to 606b76c Compare October 8, 2026 13:44
@bschimke95
bschimke95 force-pushed the fix/post-refresh-deprecated-kubelet-flags branch from bca54ed to 7671df0 Compare October 8, 2026 14:43
@bschimke95
bschimke95 force-pushed the fix/helm-upgrade-force-retry branch from 606b76c to aef892c Compare October 8, 2026 14:44
@bschimke95
bschimke95 force-pushed the fix/post-refresh-deprecated-kubelet-flags branch from 7671df0 to d2c9520 Compare October 8, 2026 18:38
Helm's 3-way merge patch for an upgrade can occasionally compute an
update the API server rejects, e.g. "cannot patch \"coredns\" with kind
Service: Service \"coredns\" is invalid: spec.ports: Required value".
Observed deterministically (reproduced on both amd64 and arm64) during
the DNS feature's reconciliation as part of an in-place Kubernetes
version upgrade, where it caused the upgrade to retry the same failing
patch indefinitely, so the Upgrade resource's phase never reached
"Completed".

Retry once with Force, which makes Helm delete and recreate the
conflicting resource(s) instead of patching them - Helm's own
documented recovery path for this class of failure.
The retry fired unconditionally on any upgrade error - a context deadline,
an RBAC denial on a new resource type, or a plain transient network blip
on the first attempt would all immediately trigger a second, destructive
whole-release Force replace for a problem that had nothing to do with a
rejected patch. Scope it to apierrors.IsInvalid, which correctly unwraps
through Helm's own "cannot patch %q" wrapping to the underlying API
server status (verified: a wrapped context.Canceled and a wrapped Forbidden
both correctly fall through to the plain error path).

Also correct the comment: Force is not scoped to the single conflicting
resource as previously described - Helm applies one force flag to the
whole release's update() loop (action.Upgrade -> kube.Client.update),
full-replacing every resource in the manifest, not just the one that
failed to patch. Documented so operators understand the actual blast
radius, since implementing true single-resource force-replace would need
a different approach than Helm's Force flag entirely.
@bschimke95
bschimke95 force-pushed the fix/helm-upgrade-force-retry branch from aef892c to b147f87 Compare October 8, 2026 18:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant