microsoft/aspire · error · InvalidOperationException

helm uninstall failed with exit code

Error message

helm uninstall failed with exit code {exitCode}

What it means

The 'helm uninstall' process that removes the release during destroy exited with a non-zero exit code, so the destroy step throws. Unlike deploy, no stderr is embedded in the message; helm's stderr is only logged at Debug level by the engine.

Solutions

  1. Run 'helm uninstall <release> -n <namespace>' manually with the same kubeconfig to see the real helm error.
  2. If the release is already gone, remove the stale deployment state section ('Helm:<environment>') or treat destroy as complete - the failure is then only bookkeeping.
  3. Check cluster connectivity and credentials (kubectl config current-context, kubectl get ns).
  4. If resources are stuck terminating due to finalizers, patch/remove the finalizers or wait for termination, then retry destroy.
Defensive patterns

Strategy: try-catch

Validate before calling

// before destroy, confirm the release still exists:
// helm status <release> -n <namespace>   (non-zero => release already gone; skip uninstall)

Try / catch

try
{
    await deploymentEngine.DestroyAsync(context);
}
catch (InvalidOperationException ex) when (ex.Message.StartsWith("helm uninstall failed"))
{
    // helm's real error is only at Debug log level; re-run with debug logging or run helm uninstall manually
    logger.LogError(ex, "Helm uninstall failed; check release/namespace state");
    throw;
}

Prevention

When it happens

Trigger: HelmUninstallAsync runs helm uninstall for the release/namespace and the process exits non-zero - e.g. the release no longer exists (already uninstalled), the cluster/context is unreachable, or the Kubernetes API rejected the delete.

Common situations: Running destroy twice (release already gone), kubeconfig credentials expired between deploy and destroy, cluster or namespace deleted out-of-band, or finalizer/termination stalls causing uninstall timeouts.

Related errors


AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16). Data as JSON: /api/errors/2d8c484f8396d5b0. Report an issue: GitHub.

Appendix: source

Thrown at src/Aspire.Hosting.Kubernetes/Deployment/HelmDeploymentEngine.cs:637

                // state cleanup failed. Keep retries idempotent without masking unrelated Helm errors.
                var arguments = $"uninstall {releaseName} --namespace {@namespace} --ignore-not-found";

                if (environment.KubeConfigPath is not null)
                {
                    arguments += $" --kubeconfig \"{environment.KubeConfigPath}\"";
                }

                context.Logger.LogDebug("Running helm {Arguments}", arguments);

                var exitCode = await helmRunner.RunAsync(
                    arguments,
                    onOutputData: output => context.Logger.LogDebug("helm (stdout): {Output}", output),
                    onErrorData: error => context.Logger.LogDebug("helm (stderr): {Error}", error),
                    cancellationToken: context.CancellationToken).ConfigureAwait(false);

                if (exitCode != 0)
                {
                    throw new InvalidOperationException($"helm uninstall failed with exit code {exitCode}");
                }
                else
                {
                    await uninstallTask.CompleteAsync(
                        new MarkdownString($"Helm release **{releaseName}** uninstalled from namespace **{@namespace}**"),
                        CompletionState.Completed,
                        context.CancellationToken).ConfigureAwait(false);
                }
            }
            catch (Exception ex) when (ex is not OperationCanceledException)
            {
                await uninstallTask.CompleteAsync(
                    $"Helm uninstall failed: {ex.Message}",
                    CompletionState.CompletedWithError,
                    context.CancellationToken).ConfigureAwait(false);
                throw;
            }
        }

View on GitHub (pinned to 25830f84bd)