helm/helm · error

unable to get waiter: %w

Error message

unable to get waiter: %w

What it means

Returned by Rollback.performRollback when constructing the waiter fails: the kube client's GetWaiterWithOptions(WaitStrategy, WaitOptions...) (when it implements kube.InterfaceWaitOptions) or GetWaiter(WaitStrategy) returns an error. The cluster resources were already updated; only the post-apply wait phase could not start. Note it returns a nil release alongside the error, unlike neighbouring failures which return targetRelease.

Source

Thrown at pkg/action/rollback.go:280

			_, 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 {
		if err := waiter.WaitWithJobs(target, r.Timeout); err != nil {
			targetRelease.SetStatus(common.StatusFailed, fmt.Sprintf("Release %q failed: %s", targetRelease.Name, err.Error()))
			r.cfg.recordRelease(currentRelease)
			r.cfg.recordRelease(targetRelease)
			return targetRelease, fmt.Errorf("release %s failed: %w", targetRelease.Name, err)
		}
	} else {
		if err := waiter.Wait(target, r.Timeout); err != nil {
			targetRelease.SetStatus(common.StatusFailed, fmt.Sprintf("Release %q failed: %s", targetRelease.Name, err.Error()))
			r.cfg.recordRelease(currentRelease)
			r.cfg.recordRelease(targetRelease)
			return targetRelease, fmt.Errorf("release %s failed: %w", targetRelease.Name, err)
		}
	}

	// post-rollback hooks

View on GitHub (pinned to 2a29f1770b)

Solutions

  1. Use strategy constants from the same helm version's kube package (e.g. kube.StatusWatcherStrategy) rather than string literals
  2. If injecting a custom KubeClient, implement GetWaiter for every strategy you pass, or implement InterfaceWaitOptions and accept/return a waiter for the strategies your code uses
  3. Log the wrapped error — it names the unsupported strategy or option
  4. Fall back to the default wait strategy (leave WaitStrategy zero / use the client default) to confirm the rest of the rollback works

Example fix

// before: custom client breaks waiter resolution
rollback := action.NewRollback(cfg)
rollback.WaitStrategy = kube.WaitStrategy("bogus")
_, err := rollback.RunWithContext(ctx, "my-release")

// after: use a supported constant from the same kube package
rollback.WaitStrategy = kube.StatusWatcherStrategy
Defensive patterns

Strategy: type-guard

Type guard

// probe the client's waiter surface before running the rollback
var waiter kube.Waiter
if c, ok := cfg.KubeClient.(kube.InterfaceWaitOptions); ok {
    waiter, err = c.GetWaiterWithOptions(strategy, opts...)
} else {
    waiter, err = cfg.KubeClient.GetWaiter(strategy)
}
if err != nil {
    return fmt.Errorf("wait strategy unsupported by client, pick another: %w", err)
}

Try / catch

if err != nil {
    if strings.Contains(err.Error(), "unable to get waiter") {
        // resources WERE applied; only the wait phase aborted.
        // verify resource state manually instead of blindly retrying the rollback.
        return verifyRollbackStateManually(ctx, targetRelease)
    }
}

Prevention

When it happens

Trigger: Passing a WaitStrategy the configured kube client does not support (e.g. a strategy name not registered in the client's wait strategy set), or wait options rejected by GetWaiterWithOptions (invalid combination such as incompatible strategy+options).

Common situations: SDK users constructing Configuration with a custom/mock KubeClient that does not implement InterfaceWaitOptions or implements it with a limited strategy registry; mismatched WaitStrategy constants between helm versions; typo'd or version-drifted strategy passed via WaitOptions.

Related errors


AI-assisted analysis of helm/helm@2a29f1770b (2026-08-15). Data as JSON: /api/errors/644e8a877a138942. Report an issue: GitHub.