GoogleContainerTools/skaffold · error · CleanupErr

kubectl delete: %w

Error message

kubectl delete: %w

What it means

The kubectl CLI wrapper runs `kubectl delete` with --ignore-not-found and --wait=false to clean up deployed resources. If the kubectl command exits non-zero, the error is wrapped as a CleanupErr. This typically means kubectl itself failed (connection, auth, invalid manifest) rather than the resource being absent.

Source

Thrown at pkg/skaffold/deploy/kubectl/cli.go:84

	JSONParseConfig() latest.JSONParseConfig
	EnablePlatformNodeAffinityInRenderedManifests() bool
	EnableGKEARMNodeTolerationInRenderedManifests() bool
}

func NewCLI(cfg Config, flags latest.KubectlFlags, defaultNamespace string) CLI {
	return CLI{
		CLI:              kubectl.NewCLI(cfg, defaultNamespace),
		Flags:            flags,
		forceDeploy:      cfg.ForceDeploy(),
		waitForDeletions: cfg.WaitForDeletions(),
	}
}

// Delete runs `kubectl delete` on a list of manifests.
func (c *CLI) Delete(ctx context.Context, out io.Writer, manifests manifest.ManifestList) error {
	args := c.args(c.Flags.Delete, "--ignore-not-found=true", "--wait=false", "-f", "-")
	if err := c.Run(ctx, manifests.Reader(), out, "delete", args...); err != nil {
		return deployerr.CleanupErr(fmt.Errorf("kubectl delete: %w", err))
	}

	return nil
}

// Apply runs `kubectl apply` on a list of manifests.
func (c *CLI) Apply(ctx context.Context, out io.Writer, manifests manifest.ManifestList) error {
	ctx, endTrace := instrumentation.StartTrace(ctx, "Apply", map[string]string{
		"AppliedBy": "kubectl",
	})
	defer endTrace()
	// Only redeploy modified or new manifests
	// TODO(dgageot): should we delete a manifest that was deployed and is not anymore?
	updated := c.previousApply.Diff(manifests)
	log.Entry(ctx).Debugf("%d manifests to deploy. %d are updated or new", len(manifests), len(updated))
	if len(updated) == 0 {
		return nil
	}

View on GitHub (pinned to a1189de023)

Solutions

  1. Run `kubectl cluster-info` with the same kubeconfig/context to verify connectivity and fix kubeconfig or credentials.
  2. Re-authenticate to the cluster (gcloud auth login / aws eks update-kubeconfig / az aks get-credentials).
  3. Run `kubectl version` to confirm the kubectl binary is compatible with the cluster.
  4. Since --ignore-not-found is set, retry cleanup after connectivity is restored.

Example fix

// before: stale context
kubectl config use-context stale-cluster
// after
kubectl config use-context my-cluster
kubectl cluster-info  # verify reachable, then re-run skaffold delete
Defensive patterns

Strategy: try-catch

Validate before calling

// Verify cluster reachability before cleanup
if err := exec.Command("kubectl", "cluster-info").Run(); err != nil {
    return fmt.Errorf("cluster unreachable, skipping cleanup: %w", err)
}

Try / catch

err := cli.Delete(ctx, out, manifests)
var cleanupErr *deployerr.CleanupErr
if errors.As(err, &cleanupErr) {
    log.Warnf("cleanup failed: %v — check kubeconfig/credentials", cleanupErr)
}

Prevention

When it happens

Trigger: c.Run(...) for `kubectl delete -f -` returns an error during Cleanup — cluster unreachable, auth expired, malformed stdin manifests, or kubectl binary issues.

Common situations: Cluster torn down or kubeconfig pointing at a dead endpoint; expired cloud credentials (gke/eks); context renamed or removed; manifests referencing APIs the cluster can't process on delete.

Related errors


AI-assisted analysis of GoogleContainerTools/skaffold@a1189de023 (2026-09-05). Data as JSON: /api/errors/4a009842127e068e. Report an issue: GitHub.