{"record":{"id":"42e9cc443401ecd1","repo":"containerd/containerd","slug":"failed-to-add-sandbox-v-into-store-w","errorCode":null,"errorMessage":"failed to add sandbox %+v into store: %w","messagePattern":"failed to add sandbox %\\+v into store: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/cri/server/sandbox_run.go","lineNumber":387,"sourceCode":"\tdefer func() {\n\t\tif retErr != nil {\n\t\t\tdeferCtx, deferCancel := util.DeferContext()\n\t\t\tdefer deferCancel()\n\t\t\tc.nri.RemovePodSandbox(deferCtx, &sandbox)\n\t\t}\n\t}()\n\n\tif err := sandbox.Status.Update(func(status sandboxstore.Status) (sandboxstore.Status, error) {\n\t\t// Set the pod sandbox as ready after successfully start sandbox container.\n\t\tstatus.State = sandboxstore.StateReady\n\t\treturn status, nil\n\t}); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to update sandbox status: %w\", err)\n\t}\n\n\t// Add sandbox into sandbox store in INIT state.\n\tif err := c.sandboxStore.Add(sandbox); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to add sandbox %+v into store: %w\", sandbox, err)\n\t}\n\t// We no longer need to stop sandbox with a cleanup defer since it is in the store.\n\trollbackSandbox = false\n\n\t// Send CONTAINER_CREATED event with both ContainerId and SandboxId equal to SandboxId.\n\t// Note that this has to be done after sandboxStore.Add() because we need to get\n\t// SandboxStatus from the store and include it in the event.\n\tc.generateAndSendContainerEvent(ctx, id, id, runtime.ContainerEventType_CONTAINER_CREATED_EVENT)\n\n\texitCh, err := c.sandboxService.WaitSandbox(util.NamespacedContext(), sandbox.Sandboxer, id)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to wait sandbox %s: %v\", id, err)\n\t}\n\n\t// start the monitor after adding sandbox into the store, this ensures\n\t// that sandbox is in the store, when event monitor receives the TaskExit event.\n\t//\n\t// TaskOOM from containerd may come before sandbox is added to store,","sourceCodeStart":369,"sourceCodeEnd":405,"githubUrl":"https://github.com/containerd/containerd/blob/4246446a2bf7d03837b0244118d858799393bd80/internal/cri/server/sandbox_run.go#L369-L405","documentation":"RunPodSandbox adds the fully started sandbox object into the persistent sandbox store (in INIT state). Failure here means the store Add rejected the entry (e.g. it already exists), and the running sandbox will be rolled back by the deferred cleanup.","triggerScenarios":"c.sandboxStore.Add(sandbox) returns an error, most commonly ErrAlreadyExists when a sandbox with the same ID is already in the store, or a metadata persistence failure.","commonSituations":"Retried RunPodSandbox after a previous partial success left a stale entry; kubelet retrying with a reused sandbox ID; underlying metadata DB write errors.","solutions":["If the error is already-exists, call RemovePodSandbox for the stale sandbox ID (or crictl stopp/rmp) and retry.","Use a fresh sandbox UID for retries (kubelet normally generates a new one per attempt).","Check metadata DB health (disk space, bolt errors) if Add fails on a clean ID.","Restart containerd to clear inconsistent in-memory state if stale entries persist."],"exampleFix":"// before: blind retry\n// after: clear stale sandbox then retry\n_, err := r.RunPodSandbox(ctx, req)\nif err != nil && strings.Contains(err.Error(), \"already exists\") {\n    _ = r.RemovePodSandbox(ctx, &runtime.RemovePodSandboxRequest{PodSandboxId: sandboxID})\n    return r.RunPodSandbox(ctx, req)\n}","handlingStrategy":"validation","validationCode":"// before RunPodSandbox with a reused ID, clear stale state\n// crictl stopp <id> ; crictl rmp <id>\n// or in Go: pods, _ := client.ListPodSandbox(ctx, &runtime.PodSandboxFilter{Id: sandboxID})","typeGuard":null,"tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"already exists\") {\n    _ = client.RemovePodSandbox(ctx, &runtime.RemovePodSandboxRequest{PodSandboxId: id})\n    return client.RunPodSandbox(ctx, req)\n}","preventionTips":["Always use a freshly generated sandbox UID per attempt.","Clean up stale sandboxes after failed runs before retrying."],"tags":["cri","sandbox","store","duplicate-id"],"backgroundTag":"sandbox-already-exists","analyzedSha":"4246446a2bf7d03837b0244118d858799393bd80","analyzedAt":"2026-09-02T00:14:43.053Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}