Helm stores one release per name per namespace, as a Secret in that namespace. The name is taken, so the install is refused.
The confusion is that helm list hides more than people expect.
Find it
helm list --all-namespaces --all --filter '^api$'
NAME NAMESPACE REVISION STATUS CHART
api production 3 failed api-1.4.2
Two flags matter:
--allincludesfailed,pending-install,pending-upgradeanduninstalling. Without it, a failed release is invisible and looks like it does not exist.--all-namespacesbecause releases are namespaced and your current context may be pointing elsewhere.
You can also see the underlying storage directly:
kubectl get secret -n production -l owner=helm,name=api
NAME TYPE AGE
sh.helm.release.v1.api.v1 helm.sh/release.v1 12d
sh.helm.release.v1.api.v2 helm.sh/release.v1 3d
One Secret per revision. That is the entire release history.
The right fix in a pipeline
helm upgrade --install api ./chart --namespace production --create-namespace
--install makes the command install if absent and upgrade if present, so the same command works on a fresh environment and an existing one. Any deployment pipeline should use this rather than helm install, and this error largely disappears.
Choosing what to do
helm status api -n production
| Status | What to do |
|---|---|
deployed | helm upgrade |
failed | helm rollback, or uninstall if there is nothing to roll back to |
pending-install | The first install is stuck. See below |
pending-upgrade | An upgrade is stuck or still running |
uninstalling | A delete is stuck, usually a finalizer |
"has no deployed releases"
Error: UPGRADE FAILED: "api" has no deployed releases
This is the same situation from the other side. The first install failed, so there is no successful revision. helm upgrade needs a deployed revision to upgrade from, and helm rollback needs one to roll back to. Neither has anything to work with.
helm history api -n production
REVISION STATUS CHART DESCRIPTION
1 failed api-1.4.2 Release "api" failed: timed out waiting
One revision, failed. Uninstall and install again:
helm uninstall api -n production
helm install api ./chart -n production
Nothing is lost, because nothing was ever successfully deployed. Do check for leftover objects first, since a partial install can leave resources behind:
kubectl get all -n production -l app.kubernetes.io/instance=api
Rolling back instead
If there is a good revision, prefer it:
helm history api -n production
helm rollback api 2 -n production
helm rollback with no revision number goes to the previous one. Note it creates a new revision that duplicates the old state rather than deleting history, so revision 4 might be a copy of revision 2.
Keeping history on uninstall
helm uninstall api -n production --keep-history
This leaves the release records in place, so the name stays reserved and helm rollback still works. Useful when you want to remove the workload temporarily and retain the ability to restore it.
Without --keep-history, all revision Secrets are deleted and the name becomes free.
Stuck in pending
helm list -n production --all
NAME REVISION STATUS
api 4 pending-upgrade
An upgrade that was interrupted, commonly a CI job cancelled or a runner that died, leaves the release in pending-upgrade and every subsequent operation refuses to proceed.
Helm 3.13 added a supported way out:
helm rollback api -n production
If that is refused, the older approach is to delete the Secret for the stuck revision so the previous one becomes current:
kubectl delete secret sh.helm.release.v1.api.v4 -n production
Make sure no operation is genuinely still running first. Deleting the record of an in-flight upgrade leaves cluster state and Helm's view of it inconsistent.
Names are per namespace
helm install api ./chart -n staging # fine
helm install api ./chart -n production # also fine, different release
Two releases called api in different namespaces are unrelated. A collision therefore means someone installed into the namespace you are targeting, which on a shared cluster is worth checking before you uninstall anything.
A checklist
helm list --all-namespaces --all --filter '^name$'. Both flags matter.- Use
helm upgrade --installin pipelines and this mostly stops happening. helm statusto decide: deployed → upgrade, failed → rollback or uninstall.has no deployed releases→ the first install failed. Uninstall, then install.- Check for orphaned objects by label before reinstalling.
- A good revision exists →
helm rollbackrather than uninstall. --keep-historyon uninstall keeps the name and the ability to roll back.- Stuck
pending-*→helm rollback, or delete the stuck revision Secret.
Frequently Asked Questions
Why does helm list not show the release that is blocking me?
Because helm list shows only deployed releases in the current namespace by default. A release in failed, pending-install or pending-upgrade state is hidden unless you pass --all, and one in a different namespace is hidden unless you pass --all-namespaces. Those two flags together reveal nearly every "the release does not exist but Helm says it does" case. You can also look at the storage directly with kubectl get secret -l owner=helm,name=<release>.
What does "has no deployed releases" mean?
The release exists but has never reached a successful state, because its first install failed. helm upgrade needs a deployed revision to upgrade from and helm rollback needs one to roll back to, so neither has anything to work with. Confirm with helm history, which will show a single failed revision. The way out is helm uninstall followed by a fresh install, which loses nothing since nothing was ever successfully deployed.
Should I use helm install or helm upgrade --install?
helm upgrade --install for anything automated. It installs when the release is absent and upgrades when it is present, so the same command works against a brand new environment and an existing one without the pipeline needing to know which it is facing. Plain helm install fails on the second run, and plain helm upgrade fails on the first, which is why pipelines using either one eventually hit an error that has nothing to do with the change being deployed.
How do I recover a release stuck in pending-upgrade?
That state usually means an upgrade was interrupted, typically a cancelled CI job or a runner that disappeared. From Helm 3.13, helm rollback handles it directly. If that is refused, delete the Secret for the stuck revision, sh.helm.release.v1.<name>.v<N>, so the previous revision becomes current again. Before doing that, make sure no operation is genuinely still in progress, because deleting the record of a live upgrade leaves the cluster and Helm's view of it inconsistent.
Does uninstalling a release delete its data?
It deletes the Kubernetes objects the release created, which includes PersistentVolumeClaims unless the chart marks them with a helm.sh/resource-policy: keep annotation. Whether the underlying volume survives then depends on the StorageClass reclaim policy. Before uninstalling anything stateful, check what the release owns with kubectl get all,pvc -l app.kubernetes.io/instance=<release>, and consider --keep-history if you want to retain the ability to roll back afterwards.