Fixing a Failed or Stuck Helm Release
Recover a failed or pending Helm release by preserving evidence, inspecting revisions and resources, testing rollback, and avoiding unsafe secret edits.
A Helm release that fails partway through an install or upgrade can leave itself in a stuck intermediate state — subsequent helm upgrade commands then fail immediately with an error about another operation already in progress, even though nothing is actually running.
Step 1: check the release’s current status
helm status myrelease
A release stuck in pending-install, pending-upgrade, or pending-rollback indicates a previous operation didn’t complete cleanly — Helm considers the release “locked” in this state until it’s explicitly resolved.
Step 2: check the release history for what actually happened
helm history myrelease
This shows every previous revision and its outcome — confirm which specific revision failed and roughly when, useful context before deciding whether to roll back or push through with a fix.
Step 3: check the actual Kubernetes resources for the real underlying error
kubectl get pods -l app.kubernetes.io/instance=myrelease
kubectl describe pod <failing-pod>
Helm’s own status often doesn’t explain why the underlying deployment failed — the actual root cause (a crashing container, a failed readiness probe, an ImagePullBackOff) is visible at the Kubernetes resource level, not in Helm’s own state tracking.
Step 4: roll back to the last known-good revision
helm rollback myrelease <last-good-revision-number>
This is usually the fastest path back to a working state — rolling back to the most recent revision that was confirmed working, rather than continuing to debug the failed upgrade in place.
Step 5: if rollback itself fails, or no good revision exists, force-unlock the release
kubectl get secret -l "owner=helm,name=myrelease" -n <namespace>
Helm 3 tracks release state as Kubernetes secrets — in stubborn cases, understanding this storage lets you inspect the release state directly rather than only through Helm’s own commands, though modifying these secrets directly should be a last resort after other options are exhausted.
Do not delete or hand-edit the latest release Secret merely to clear pending-upgrade. It contains Helm’s revision record, and changing it can create an inconsistent history. First confirm no Helm process, GitOps controller, or CI job still owns the operation. Export helm status, helm history, helm get all, relevant events, and release Secrets before exceptional recovery.
Step 6: fix the underlying chart or values problem before retrying
helm upgrade myrelease ./mychart --dry-run --debug
--dry-run --debug renders the exact manifests Helm would apply, without actually applying them — use this to catch a templating error or invalid configuration before attempting the real upgrade again, rather than repeating the same failure.
Step 7: retry the upgrade once the underlying issue is fixed
helm upgrade myrelease ./mychart -f values.yaml
Step 8: use --atomic going forward to avoid this class of problem entirely
helm upgrade myrelease ./mychart --atomic
The --atomic flag makes an upgrade roll back changes when it fails and implies waiting for readiness. Supply a realistic --timeout; otherwise a healthy but slow migration can be classified as failed. Atomic rollback cannot reverse external side effects, destructive database changes, or every hook action.
Verify recovery at three layers
After rollback or repair, confirm Helm reports the intended revision, Kubernetes workloads are Ready, and a real application smoke test succeeds. Inspect the deployed image digest and configuration because a deployed Helm state does not prove the service is functional.
Reproduce the failed upgrade in a disposable cluster with the same chart, values, capabilities, and CRDs. Use helm lint, helm template, and server-side dry run where appropriate. Test supported upgrades from the previous release rather than only clean installations.
Serialize release operations in CI so two jobs cannot upgrade the same name concurrently. Protect chart and values changes with review, pin dependencies and images, and bound release history. If direct Secret recovery is unavoidable, follow a documented, version-specific procedure with a backup and explicit rollback point rather than improvising against encoded storage.
Why understanding Helm’s release-state tracking matters here
Helm releases carry their own state (stored as Kubernetes secrets in Helm 3) tracking whether an operation is in progress, completed, or failed — a release stuck mid-operation isn’t a Kubernetes-level problem at all, it’s Helm’s own bookkeeping not having been updated cleanly after an interrupted operation. Recognizing this distinction is why helm rollback (operating on Helm’s own state) is usually the right first move, rather than troubleshooting Kubernetes resources directly for what’s actually a Helm-level state problem.
Related:
- Helm Is Born at the First KubeCon, Modeled on Homebrew and apt
- Fixing ImagePullBackOff in Kubernetes
Sources: