{"record":{"id":"4b15b5eabaa26e7a","repo":"containerd/containerd","slug":"failed-to-get-task-status-w","errorCode":null,"errorMessage":"failed to get task status: %w","messagePattern":"failed to get task status: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/cri/server/podsandbox/recover.go","lineNumber":114,"sourceCode":"\t\tstatus.CreatedAt = info.CreatedAt\n\n\t\t// Load sandbox state.\n\t\tt, err := cntr.Task(ctx, nil)\n\t\tif err != nil && !errdefs.IsNotFound(err) {\n\t\t\treturn status, channel, fmt.Errorf(\"failed to load task: %w\", err)\n\t\t}\n\t\tvar taskStatus containerd.Status\n\t\tvar notFound bool\n\t\tif errdefs.IsNotFound(err) {\n\t\t\t// Task is not found.\n\t\t\tnotFound = true\n\t\t} else {\n\t\t\t// Task is found. Get task status.\n\t\t\ttaskStatus, err = t.Status(ctx)\n\t\t\tif err != nil {\n\t\t\t\t// It's still possible that task is deleted during this window.\n\t\t\t\tif !errdefs.IsNotFound(err) {\n\t\t\t\t\treturn status, channel, fmt.Errorf(\"failed to get task status: %w\", err)\n\t\t\t\t}\n\t\t\t\tnotFound = true\n\t\t\t}\n\t\t}\n\t\tif notFound {\n\t\t\t// Task does not exist, set sandbox state as NOTREADY.\n\t\t\tstatus.State = sandboxstore.StateNotReady\n\t\t} else {\n\t\t\tif taskStatus.Status == containerd.Running {\n\t\t\t\texitCh, err := t.Wait(ctrdutil.NamespacedContext())\n\t\t\t\tif err != nil {\n\t\t\t\t\tif !errdefs.IsNotFound(err) {\n\t\t\t\t\t\treturn status, channel, fmt.Errorf(\"failed to wait for sandbox container task: %w\", err)\n\t\t\t\t\t}\n\t\t\t\t\tstatus.State = sandboxstore.StateNotReady\n\t\t\t\t} else {\n\t\t\t\t\tstatus.State = sandboxstore.StateReady\n\t\t\t\t\tstatus.Pid = t.Pid()","sourceCodeStart":96,"sourceCodeEnd":132,"githubUrl":"https://github.com/containerd/containerd/blob/4246446a2bf7d03837b0244118d858799393bd80/internal/cri/server/podsandbox/recover.go#L96-L132","documentation":"When the task handle loads successfully during sandbox recovery, the code calls t.Status(ctx) to get its current state. If Status fails with a non-NotFound error, it is wrapped with this message. Since the task existed a moment earlier, a NotFound here is treated as the task being deleted in the window; any other error indicates a real failure querying task state from the shim/containerd.","triggerScenarios":"RecoverContainer startup path: t.Status(ctx) returns e.g. an RPC timeout, shim IO error, or transport failure while talking to the sandbox's shim process.","commonSituations":"Shim process hung or dead but task record still present; containerd-to-shim connection broken after daemon restart; resource exhaustion (fd/memory) on the node causing RPC failures.","solutions":["Inspect the wrapped error for RPC/transport vs shim crash causes","Restart containerd so it reconnects to or cleans up shims, then allow recovery to re-run","Check node resources (fds, memory) and shim logs (journalctl -u containerd) for the failing shim","If the shim is unrecoverable, delete the sandbox container record and let the kubelet recreate the pod"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"taskStatus, err = t.Status(ctx)\nif err != nil && !errdefs.IsNotFound(err) {\n  // retry once after reconnect; transient shim RPC failures often clear\n  time.Sleep(100 * time.Millisecond)\n  taskStatus, err = t.Status(ctx)\n  if err != nil && !errdefs.IsNotFound(err) {\n    return fmt.Errorf(\"failed to get task status: %w\", err)\n  }\n}","preventionTips":["Monitor node fd/memory limits that starve shim RPCs","Restart containerd if shim connections degrade after daemon restarts","Pin containerd client/daemon versions to compatible pairs"],"tags":["containerd","task","status","shim","recovery"],"backgroundTag":"task-status-rpc-failed","analyzedSha":"4246446a2bf7d03837b0244118d858799393bd80","analyzedAt":"2026-09-02T00:14:43.053Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}