{"record":{"id":"6d3af109e29a7e8b","repo":"GoogleContainerTools/skaffold","slug":"d-resources-failed-to-complete-their-deletion-bef","errorCode":null,"errorMessage":"%d resources failed to complete their deletion before a new deployment: %s","messagePattern":"(.+?) resources failed to complete their deletion before a new deployment: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/skaffold/deploy/kubectl/cli.go","lineNumber":146,"sourceCode":"\t} `json:\"items\"`\n}\n\n// WaitForDeletions waits for resource marked for deletion to complete their deletion.\nfunc (c *CLI) WaitForDeletions(ctx context.Context, out io.Writer, manifests manifest.ManifestList) error {\n\tif !c.waitForDeletions.Enabled {\n\t\treturn nil\n\t}\n\n\tctx, cancel := context.WithTimeout(ctx, c.waitForDeletions.Max)\n\tdefer cancel()\n\n\tpreviousList := \"\"\n\tpreviousCount := 0\n\n\tfor {\n\t\tselect {\n\t\tcase <-ctx.Done():\n\t\t\treturn waitForDeletionErr(fmt.Errorf(\"%d resources failed to complete their deletion before a new deployment: %s\", previousCount, previousList))\n\t\tdefault:\n\t\t\t// List resources in json format.\n\t\t\tbuf, err := c.RunOutInput(ctx, manifests.Reader(), \"get\", c.args(nil, \"-f\", \"-\", \"--ignore-not-found\", \"-ojson\")...)\n\t\t\tif err != nil {\n\t\t\t\treturn waitForDeletionErr(err)\n\t\t\t}\n\n\t\t\t// No resource found.\n\t\t\tif len(buf) == 0 {\n\t\t\t\treturn nil\n\t\t\t}\n\n\t\t\t// Find which ones are marked for deletion. They have a `metadata.deletionTimestamp` field.\n\t\t\tvar result getResult\n\t\t\tif err := json.Unmarshal(buf, &result); err != nil {\n\t\t\t\treturn waitForDeletionErr(err)\n\t\t\t}\n","sourceCodeStart":128,"sourceCodeEnd":164,"githubUrl":"https://github.com/GoogleContainerTools/skaffold/blob/a1189de023efc32d4b8e11f395acc678aa555011/pkg/skaffold/deploy/kubectl/cli.go#L128-L164","documentation":"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.","triggerScenarios":"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).","commonSituations":"Namespaces stuck Terminating due to finalizers; PVCs or webhooks blocking pod deletion; very slow cluster; too-short skaffold status/deletion timeout.","solutions":["Inspect the listed resources: `kubectl get <resources>` and remove blocking finalizers (`kubectl patch <res> -p '{\"metadata\":{\"finalizers\":[]}}' --type=merge`).","Delete the parent namespace if it is stuck Terminating and re-create it.","Increase the deletion wait timeout / check for slow storage teardown (e.g. AWS EBS volume detach).","Check for validating webhook outages that block DELETE requests."],"exampleFix":"// before: stuck resource with finalizer\nkubectl get pod mypod -o jsonpath='{.metadata.finalizers}'\n// after\nkubectl patch pod mypod -p '{\"metadata\":{\"finalizers\":null}}' --type=merge","handlingStrategy":"retry","validationCode":"// Check for stuck resources before triggering a new deployment\nout, _ := exec.Command(\"kubectl\", \"get\", \"-f\", file, \"--ignore-not-found\", \"-ojson\").Output()\nif len(strings.TrimSpace(string(out))) > 0 && strings.Contains(string(out), \"Terminating\") {\n    return fmt.Errorf(\"resources still terminating; clear finalizers first\")\n}","typeGuard":null,"tryCatchPattern":"if err := cli.WaitForDeletions(ctx, out, manifests); err != nil {\n    var wd waitForDeletionErr\n    if errors.As(err, &wd) {\n        // list stuck resources, clear finalizers, then retry\n    }\n}","preventionTips":["Monitor for resources stuck in Terminating (finalizers) before redeploying","Increase deletion wait timeout in slow-storage environments","Keep validating webhooks highly available so DELETEs aren't blocked","Clean up stuck namespaces proactively"],"tags":["kubectl","kubernetes","deletion","timeout","finalizers"],"backgroundTag":"resource-deletion-timeout","analyzedSha":"a1189de023efc32d4b8e11f395acc678aa555011","analyzedAt":"2026-09-05T12:09:27.064Z","contentChangedAt":"2026-09-05T12:09:27.064Z","schemaVersion":2},"datasetVersion":"2026-09-12T17:17:11.597Z"}