DevOpsil
Kubernetes
85%
Needs Review

Fix Helm 'UPGRADE FAILED: has no deployed releases'

Zara BlackwoodZara Blackwood3 min read

The Error: "has no deployed releases"

You run helm upgrade --install and get:

Error: UPGRADE FAILED: "my-app" has no deployed releases

This is confusing because you're using the --install flag, which should handle first-time installs. But Helm still refuses.

Root Cause

This happens when a previous helm install (or helm upgrade --install) failed partway through. The release exists in Helm's history with a failed status, but no revision was ever successfully deployed. Helm sees an existing release (so it tries upgrade), but the upgrade logic requires at least one deployed revision to diff against. Since none exists, it errors out.

helm history my-app -n your-namespace
REVISION  STATUS  CHART          DESCRIPTION
1         failed  my-app-1.0.0   Install complete (failed)

That single failed revision is the culprit.

Step-by-Step Fix

Option A: Uninstall and Reinstall (Safest)

If the application was never successfully running:

# Remove the failed release
helm uninstall my-app -n your-namespace

# Install fresh
helm install my-app ./my-chart -n your-namespace -f values.yaml

Or in one step if you prefer upgrade --install:

helm uninstall my-app -n your-namespace 2>/dev/null; \
helm upgrade --install my-app ./my-chart -n your-namespace -f values.yaml

Option B: Force Replace the Failed Release

If you want to keep using upgrade --install in a CI/CD pipeline without two steps:

helm upgrade --install my-app ./my-chart \
  -n your-namespace \
  -f values.yaml \
  --force \
  --reset-values

Note: --force replaces resources using delete/recreate, which causes brief downtime.

Option C: Delete the Failed Release Secret Manually

If helm uninstall itself fails:

# List all release secrets
kubectl get secrets -n your-namespace -l "owner=helm,name=my-app"

# Delete them all
kubectl delete secrets -n your-namespace -l "owner=helm,name=my-app"

# Now install fresh
helm upgrade --install my-app ./my-chart -n your-namespace -f values.yaml

Option D: Fix in CI/CD Pipelines

For automated pipelines, wrap the logic to handle this case:

#!/bin/bash
set -e

RELEASE="my-app"
NAMESPACE="production"
CHART="./my-chart"

# Check if release exists and has only failed revisions
STATUS=$(helm status "$RELEASE" -n "$NAMESPACE" -o json 2>/dev/null | jq -r '.info.status' || echo "not-found")

if [ "$STATUS" = "failed" ]; then
  echo "Found failed release, uninstalling first..."
  helm uninstall "$RELEASE" -n "$NAMESPACE" --wait
fi

helm upgrade --install "$RELEASE" "$CHART" \
  -n "$NAMESPACE" \
  -f values.yaml \
  --wait \
  --timeout 5m0s

Verify the Fix

helm list -n your-namespace

You should see:

NAME     NAMESPACE   REVISION  STATUS    CHART
my-app   production  1         deployed  my-app-1.0.0

Also check that the actual workloads are running:

kubectl get pods -n your-namespace -l app.kubernetes.io/instance=my-app

Prevention Tips

  • Always use --atomic in CI/CD: helm upgrade --install --atomic --timeout 5m0s. This auto-rolls back on failure, leaving the release in a clean state instead of failed.
  • Use --wait so Helm waits for pods to be ready and properly records success or failure.
  • Fix the root cause of the initial failure (bad image tag, missing secrets, resource limits) before retrying. Blindly rerunning the pipeline hits the same error.
  • Add the uninstall-on-failed pattern to your CI/CD scripts as shown in Option D above.
  • Test chart changes locally with helm template and helm lint before pushing to CI.
Share:

Was this article helpful?

Zara Blackwood
Zara Blackwood

Platform Engineer

Terraform enthusiast, platform builder, DRY advocate. I believe infrastructure should be versioned, reviewed, and deployed like any other code. GitOps or bust.

Related Articles

More in Kubernetes

View all →

Discussion