{"record":{"id":"eaa92635fb76e863","repo":"containerd/containerd","slug":"failed-to-handle-sandbox-taskexit-event-w","errorCode":null,"errorMessage":"failed to handle sandbox TaskExit event: %w","messagePattern":"failed to handle sandbox TaskExit event: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/cri/server/events.go","lineNumber":343,"sourceCode":"\tdefer cancel()\n\n\tswitch e := any.(type) {\n\tcase *eventtypes.TaskExit:\n\t\tlog.L.Infof(\"TaskExit event %+v\", e)\n\t\t// Use ID instead of ContainerID to rule out TaskExit event for exec.\n\t\tcntr, err := ce.c.containerStore.Get(e.ID)\n\t\tif err == nil {\n\t\t\tif err := ce.c.handleContainerExit(ctx, e, cntr, cntr.SandboxID); err != nil {\n\t\t\t\treturn fmt.Errorf(\"failed to handle container TaskExit event: %w\", err)\n\t\t\t}\n\t\t\treturn nil\n\t\t} else if !errdefs.IsNotFound(err) {\n\t\t\treturn fmt.Errorf(\"can't find container for TaskExit event: %w\", err)\n\t\t}\n\t\tsb, err := ce.c.sandboxStore.Get(e.ID)\n\t\tif err == nil {\n\t\t\tif err := ce.c.handleSandboxExit(ctx, sb, e.ExitStatus, e.ExitedAt.AsTime()); err != nil {\n\t\t\t\treturn fmt.Errorf(\"failed to handle sandbox TaskExit event: %w\", err)\n\t\t\t}\n\t\t\treturn nil\n\t\t} else if !errdefs.IsNotFound(err) {\n\t\t\treturn fmt.Errorf(\"can't find sandbox for TaskExit event: %w\", err)\n\t\t}\n\t\treturn nil\n\tcase *eventtypes.SandboxExit:\n\t\tlog.L.Infof(\"SandboxExit event %+v\", e)\n\t\tsb, err := ce.c.sandboxStore.Get(e.GetSandboxID())\n\t\tif err == nil {\n\t\t\tif err := ce.c.handleSandboxExit(ctx, sb, e.ExitStatus, e.ExitedAt.AsTime()); err != nil {\n\t\t\t\treturn fmt.Errorf(\"failed to handle sandbox TaskExit event: %w\", err)\n\t\t\t}\n\t\t\treturn nil\n\t\t} else if !errdefs.IsNotFound(err) {\n\t\t\treturn fmt.Errorf(\"can't find sandbox for TaskExit event: %w\", err)\n\t\t}\n\t\treturn nil","sourceCodeStart":325,"sourceCodeEnd":361,"githubUrl":"https://github.com/containerd/containerd/blob/4246446a2bf7d03837b0244118d858799393bd80/internal/cri/server/events.go#L325-L361","documentation":"When a TaskExit event belongs to a sandbox rather than a pod container (container store lookup was NotFound), HandleEvent delegates to handleSandboxExit. This error wraps failures of that handler — e.g. sb.Status.Update failing — for the TaskExit event path. The sandbox exit handler transitions the sandbox to NotReady and propagates the stop to waiters.","triggerScenarios":"TaskExit event whose ID resolves in the sandbox store, and sb.Status.Update fails (concurrent sandbox removal or metadata write error), raising 'failed to update sandbox state: %w' which this wrapper re-raises.","commonSituations":"Race between sandbox removal by kubelet and the exit event processing; metadata DB write failure under load; sandbox record already cleaned but event requeued by backoff.","solutions":["Check the wrapped 'failed to update sandbox state' error; if the sandbox was removed concurrently it is benign","Allow event backoff to retry; stale events for removed sandboxes are skipped on retry","Check metadata store health (disk IO, bolt errors) if persistent","Verify sandbox lifecycle: crictl pods -a to see stale sandboxes"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Go: confirm sandbox still exists before deeper handling:\nsb, err := sandboxStore.Get(e.ID)\nif errdefs.IsNotFound(err) {\n    return nil // sandbox already gone\n}","typeGuard":null,"tryCatchPattern":"if err := handleSandboxExit(ctx, sb, exitStatus, exitedAt); err != nil {\n    if strings.Contains(err.Error(), \"failed to update sandbox state\") {\n        // likely concurrent removal; retry via backoff, skip when NotFound on retry\n        monitor.Backoff(id, e)\n    }\n    return fmt.Errorf(\"failed to handle sandbox TaskExit event: %w\", err)\n}","preventionTips":["Avoid deleting sandboxes while their exit events are pending (kubelet/cri timing)","Watch metadata DB write errors in containerd logs","Let backoff retries resolve races with concurrent sandbox removal","Verify with crictl pods -a that sandbox state converges after retries"],"tags":["containerd","cri","sandbox","state-update"],"backgroundTag":"sandbox-exit-handling-failed","analyzedSha":"4246446a2bf7d03837b0244118d858799393bd80","analyzedAt":"2026-09-02T00:14:43.053Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}