helm/helm · critical
an error occurred while cleaning up resources. original roll
Error message
an error occurred while cleaning up resources. original rollback error: %w
What it means
Thrown by Rollback.performUpgrade when a rollback's Kubernetes Update() call already failed (release marked failed/superseded), the user enabled CleanupOnFail, and the follow-up attempt to delete the newly created resources (results.Created) also failed. It wraps the original rollback error as cause with the cleanup failure nested inside, so nothing is silently lost. It means the cluster is left in a partially rolled-back state that Helm cannot clean up automatically.
Source
Thrown at pkg/action/rollback.go:264
current,
target,
kube.ClientUpdateOptionForceReplace(r.ForceReplace),
kube.ClientUpdateOptionServerSideApply(serverSideApply, r.ForceConflicts),
kube.ClientUpdateOptionThreeWayMergeForUnstructured(false),
kube.ClientUpdateOptionUpgradeClientSideFieldManager(true))
if err != nil {
msg := fmt.Sprintf("Rollback %q failed: %s", targetRelease.Name, err)
r.cfg.Logger().Warn(msg)
currentRelease.Info.Status = common.StatusSuperseded
targetRelease.Info.Status = common.StatusFailed
targetRelease.Info.Description = msg
r.cfg.recordRelease(currentRelease)
r.cfg.recordRelease(targetRelease)
if r.CleanupOnFail {
r.cfg.Logger().Debug("cleanup on fail set, cleaning up resources", "count", len(results.Created))
_, errs := r.cfg.KubeClient.Delete(results.Created, metav1.DeletePropagationBackground)
if errs != nil {
return targetRelease, fmt.Errorf(
"an error occurred while cleaning up resources. original rollback error: %w",
fmt.Errorf("unable to cleanup resources: %w", joinErrors(errs, ", ")))
}
r.cfg.Logger().Debug("resource cleanup complete")
}
return targetRelease, err
}
var waiter kube.Waiter
if c, supportsOptions := r.cfg.KubeClient.(kube.InterfaceWaitOptions); supportsOptions {
waiter, err = c.GetWaiterWithOptions(r.WaitStrategy, r.WaitOptions...)
} else {
waiter, err = r.cfg.KubeClient.GetWaiter(r.WaitStrategy)
}
if err != nil {
return nil, fmt.Errorf("unable to get waiter: %w", err)
}
if r.WaitForJobs {View on GitHub (pinned to 2a29f1770b)
Solutions
- Inspect the wrapped chain: the outer message names cleanup, the inner 'unable to cleanup resources' lists per-resource delete errors, and %w carries the original rollback error — fix that root cause first
- Manually delete the leftover created resources with kubectl (match what the rollback had just created; check release manifest and events)
- Verify RBAC: the identity needs delete on every resource kind the chart creates, not just create/update
- Retry the rollback after the root cause is fixed; check 'helm history' and 'kubectl get events' to confirm the failed/created set
- If a webhook/finalizer blocks deletes, remove the finalizer or exempt the rollback identity before retrying
Defensive patterns
Strategy: try-catch
Try / catch
res, err := rollback.RunWithContext(ctx, name)
if err != nil {
if strings.Contains(err.Error(), "an error occurred while cleaning up resources") {
// release marked failed in storage; cluster partially rolled back
var cleanupInner *myJoinErr // unwrap chain: outer %w -> inner "unable to cleanup resources"
if inner := errors.Unwrap(errors.Unwrap(err)); inner != nil {
log.Printf("per-resource delete failures: %v", inner)
}
// audit created-but-not-deleted resources before retrying
}
return err
} Prevention
- Only set CleanupOnFail when the identity also holds delete on all chart kinds
- Run rollback in automation that snapshots kubectl get for the release's resources before/after, so partial cleanup is detectable
- Avoid admission webhooks that add finalizers blocking deletion of chart resources
- Serialize rollbacks per release to prevent concurrent delete races
When it happens
Trigger: helm rollback with --cleanup-on-fail where KubeClient.Update returns an error after creating some resources, and the subsequent KubeClient.Delete(results.Created, DeletePropagationBackground) returns at least one error. Programmatic equivalent: Rollback action with CleanupOnFail=true, a failing cluster update, then failing deletes (RBAC denial on delete, resource already being garbage-collected, API timeout).
Common situations: ServiceAccount lacks delete permissions but has create/update; cluster admission controllers (e.g. finalizer-adding webhooks) block deletion; network disruption to the API server mid-rollback; resources created with ownerReferences that propagate deletes unexpectedly; concurrent operator fighting the rollback.
Related errors
- unable to cleanup resources: %w
- an error occurred while finding last successful release. ori
- could not get information about the resource: %w
- failed to create resource: %w
- failed to delete resource namespace=%s, name=%s, kind=%s: %w
AI-assisted analysis of helm/helm@2a29f1770b (2026-08-15).
Data as JSON: /api/errors/492a7e9a3c6aa6b5.
Report an issue: GitHub.