← Debugging Guides

阅读中文版本

Helm Upgrade Failed — Release Stuck in pending-upgrade

Fix Helm upgrades stuck at "another operation in progress" by rolling back pending releases, using atomic and wait, and inspecting release history.

intermediatedebuggingkuberneteshelmdeployment

Symptoms

  • helm upgrade fails with "another operation (install/upgrade/rollback) is in progress"
  • The release status shows pending-upgrade or pending-install
  • A previous upgrade was interrupted (timeout or kill)

Possible causes

  • A prior upgrade left the release locked in a pending state
  • The upgrade timed out waiting for resources and never marked complete
  • Concurrent CI jobs ran upgrades for the same release

Diagnosis steps

Inspect release history and status

helm history <release> -n <ns> && helm status <release> -n <ns>

Interpretation

The history shows the pending revision that must be rolled back or superseded.

Roll back the pending release

helm rollback <release> <last-good-revision> -n <ns> --wait

Interpretation

Rolling back to the last deployed revision clears the lock and restores a known state.

Root cause

Helm records a release status in a secret/configmap and refuses a new operation while one is pending. An interrupted upgrade leaves that pending status, so subsequent operations are blocked until it is rolled back or resolved.

Fix

Roll back to the last good revision, then use --atomic --wait so failed upgrades auto-rollback, set a timeout, and serialize upgrades so concurrent jobs do not collide.

Risk note

Deleting the pending release secret manually can corrupt Helm state; prefer rollback or a controlled uninstall.

Verify the fix

Run the upgrade again and confirm it completes; verify helm history shows the new revision deployed and status deployed.

Symptoms

This debugging guide addresses “Helm Upgrade Failed — Release Stuck in pending-upgrade”. Start from the symptoms, follow the ordered diagnostics, and confirm each hypothesis before moving on; the fix and verification steps then close the loop.

Observed symptoms include:

  • helm upgrade fails with “another operation (install/upgrade/rollback) is in progress”
  • The release status shows pending-upgrade or pending-install
  • A previous upgrade was interrupted (timeout or kill)

Reproduce and Diagnose

Reproduce the failure in isolation before changing any code. Work through the checks below in order; each one narrows the search space.

Step 1: Inspect release history and status

helm history <release> -n <ns> && helm status <release> -n <ns>

The history shows the pending revision that must be rolled back or superseded.

Step 2: Roll back the pending release

helm rollback <release> <last-good-revision> -n <ns> --wait

Rolling back to the last deployed revision clears the lock and restores a known state.

Likely contributors, in order of frequency:

  • A prior upgrade left the release locked in a pending state
  • The upgrade timed out waiting for resources and never marked complete
  • Concurrent CI jobs ran upgrades for the same release

Root Cause

Helm records a release status in a secret/configmap and refuses a new operation while one is pending. An interrupted upgrade leaves that pending status, so subsequent operations are blocked until it is rolled back or resolved.

The Fix

Roll back to the last good revision, then use –atomic –wait so failed upgrades auto-rollback, set a timeout, and serialize upgrades so concurrent jobs do not collide.

Watch out: Deleting the pending release secret manually can corrupt Helm state; prefer rollback or a controlled uninstall.

# inspect and recover
helm history myapp -n prod
helm rollback myapp 3 -n prod --wait

# upgrade safely: auto-rollback on failure, wait for readiness
helm upgrade myapp ./chart -n prod \
  --atomic --wait --timeout 5m

# serialize upgrades in CI to avoid concurrent locks
# (use a concurrency group / lock in your pipeline)

Verify and Prevent

Run the upgrade again and confirm it completes; verify helm history shows the new revision deployed and status deployed.

Once verified, add a regression test that reproduces the original symptom so the failure cannot silently return.

This class of failure is usually environmental rather than pure logic, so capture the exact command, the environment variables, and the working directory in your bug report. Reproduce it in the smallest possible script, then widen the scope only once the minimal case is understood. A short written checklist for this failure mode saves hours the next time it appears.