GoogleContainerTools/skaffold · error

%d resources failed to complete their deletion before a new

Error message

%d resources failed to complete their deletion before a new deployment: %s

What it means

Before applying new manifests, the kubectl deployer waits for previously deleted resources to actually disappear, polling `kubectl get -f - --ignore-not-found -ojson`. If the context deadline expires while resources still exist, it reports how many resources and which ones failed to delete in time. This prevents applying a new deployment on top of still-terminating resources.

Source

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

	} `json:"items"`
}

// WaitForDeletions waits for resource marked for deletion to complete their deletion.
func (c *CLI) WaitForDeletions(ctx context.Context, out io.Writer, manifests manifest.ManifestList) error {
	if !c.waitForDeletions.Enabled {
		return nil
	}

	ctx, cancel := context.WithTimeout(ctx, c.waitForDeletions.Max)
	defer cancel()

	previousList := ""
	previousCount := 0

	for {
		select {
		case <-ctx.Done():
			return waitForDeletionErr(fmt.Errorf("%d resources failed to complete their deletion before a new deployment: %s", previousCount, previousList))
		default:
			// List resources in json format.
			buf, err := c.RunOutInput(ctx, manifests.Reader(), "get", c.args(nil, "-f", "-", "--ignore-not-found", "-ojson")...)
			if err != nil {
				return waitForDeletionErr(err)
			}

			// No resource found.
			if len(buf) == 0 {
				return nil
			}

			// Find which ones are marked for deletion. They have a `metadata.deletionTimestamp` field.
			var result getResult
			if err := json.Unmarshal(buf, &result); err != nil {
				return waitForDeletionErr(err)
			}

View on GitHub (pinned to a1189de023)

Solutions

  1. Inspect the listed resources: `kubectl get <resources>` and remove blocking finalizers (`kubectl patch <res> -p '{"metadata":{"finalizers":[]}}' --type=merge`).
  2. Delete the parent namespace if it is stuck Terminating and re-create it.
  3. Increase the deletion wait timeout / check for slow storage teardown (e.g. AWS EBS volume detach).
  4. Check for validating webhook outages that block DELETE requests.

Example fix

// before: stuck resource with finalizer
kubectl get pod mypod -o jsonpath='{.metadata.finalizers}'
// after
kubectl patch pod mypod -p '{"metadata":{"finalizers":null}}' --type=merge
Defensive patterns

Strategy: retry

Validate before calling

// Check for stuck resources before triggering a new deployment
out, _ := exec.Command("kubectl", "get", "-f", file, "--ignore-not-found", "-ojson").Output()
if len(strings.TrimSpace(string(out))) > 0 && strings.Contains(string(out), "Terminating") {
    return fmt.Errorf("resources still terminating; clear finalizers first")
}

Try / catch

if err := cli.WaitForDeletions(ctx, out, manifests); err != nil {
    var wd waitForDeletionErr
    if errors.As(err, &wd) {
        // list stuck resources, clear finalizers, then retry
    }
}

Prevention

When it happens

Trigger: The WaitForDeletions polling loop hits ctx.Done() while previousCount > 0 — resources stuck Terminating (finalizers) or deletion very slow for the listed resources (previousList names them).

Common situations: Namespaces stuck Terminating due to finalizers; PVCs or webhooks blocking pod deletion; very slow cluster; too-short skaffold status/deletion timeout.

Related errors


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