Fixing a Failed or Stuck Helm Release
A helm upgrade fails partway, or a release gets stuck in 'pending-upgrade' state, blocking every subsequent operation on it. Here's how to actually recover instead of getting stuck retrying the same failing command.
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.
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 Helm automatically roll back to the previous release on failure, rather than leaving the release in a stuck intermediate state — adopting this as standard practice prevents most future occurrences of the exact problem this whole troubleshooting path exists to resolve.
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.