containerd/containerd · error
can't find sandbox for TaskExit event: %w
Error message
can't find sandbox for TaskExit event: %w
What it means
HandleEvent returns this when neither the container store nor the sandbox store can resolve a TaskExit event's ID — and the sandbox lookup failed with an error other than NotFound. Since NotFound from both stores means the ID is unknown and is silently ignored, a non-NotFound error here indicates the sandbox store lookup machinery itself failed.
Source
Thrown at internal/cri/server/events.go:347
log.L.Infof("TaskExit event %+v", e)
// Use ID instead of ContainerID to rule out TaskExit event for exec.
cntr, err := ce.c.containerStore.Get(e.ID)
if err == nil {
if err := ce.c.handleContainerExit(ctx, e, cntr, cntr.SandboxID); err != nil {
return fmt.Errorf("failed to handle container TaskExit event: %w", err)
}
return nil
} else if !errdefs.IsNotFound(err) {
return fmt.Errorf("can't find container for TaskExit event: %w", err)
}
sb, err := ce.c.sandboxStore.Get(e.ID)
if err == nil {
if err := ce.c.handleSandboxExit(ctx, sb, e.ExitStatus, e.ExitedAt.AsTime()); err != nil {
return fmt.Errorf("failed to handle sandbox TaskExit event: %w", err)
}
return nil
} else if !errdefs.IsNotFound(err) {
return fmt.Errorf("can't find sandbox for TaskExit event: %w", err)
}
return nil
case *eventtypes.SandboxExit:
log.L.Infof("SandboxExit event %+v", e)
sb, err := ce.c.sandboxStore.Get(e.GetSandboxID())
if err == nil {
if err := ce.c.handleSandboxExit(ctx, sb, e.ExitStatus, e.ExitedAt.AsTime()); err != nil {
return fmt.Errorf("failed to handle sandbox TaskExit event: %w", err)
}
return nil
} else if !errdefs.IsNotFound(err) {
return fmt.Errorf("can't find sandbox for TaskExit event: %w", err)
}
return nil
case *eventtypes.TaskOOM:
log.L.Infof("TaskOOM event %+v", e)
// For TaskOOM, we only care which container it belongs to.
cntr, err := ce.c.containerStore.Get(e.ContainerID)View on GitHub (pinned to 4246446a2b)
Solutions
- Check containerd daemon logs for sandbox store / bolt errors
- Restart containerd; the backoff monitor will redeliver the event
- Inspect wrapped error chain for the underlying store cause
- If persistent, inspect the containerd root metadata DB integrity
Defensive patterns
Strategy: try-catch
Validate before calling
// Go: exit early on NotFound from container store, then guard sandbox lookup:
cntr, err := containerStore.Get(e.ID)
if errdefs.IsNotFound(err) {
sb, serr := sandboxStore.Get(e.ID)
if serr != nil && !errdefs.IsNotFound(serr) {
return fmt.Errorf("can't find sandbox for TaskExit event: %w", serr)
}
} Type guard
func isSandboxLookupFailure(err error) bool {
return err != nil && !errdefs.IsNotFound(err)
} Try / catch
if err := HandleEvent(ev); err != nil {
if isSandboxLookupFailure(err) {
log.L.WithError(err).Errorf("sandbox store failure; restart may be required")
}
// NotFound from both stores is intentionally ignored
} Prevention
- Check bolt metadata DB integrity if lookups fail for known IDs
- Restart containerd after unclean shutdown that may corrupt store state
- Only NotFound from both stores is safe to ignore silently
- Verify event IDs correspond to real containers/sandboxes (ID vs ContainerID confusion for exec)
When it happens
Trigger: containerStore.Get(e.ID) returns NotFound, then sandboxStore.Get(e.ID) returns a non-NotFound error (metadata DB failure, transport error, store corruption) while handling *eventtypes.TaskExit.
Common situations: containerd metadata bolt DB failure under load; daemon shutdown mid-event; store corruption after crash; upgrade leaving inconsistent store state.
Related errors
- sandbox %q not found: %w
- untrusted workload with explicit runtime handler is not allo
- untrusted workload with host access is not allowed
- failed to query sandbox platform: %w
- unable to get sandbox %q runtime info: %w
AI-assisted analysis of containerd/containerd@4246446a2b (2026-09-02).
Data as JSON: /api/errors/5cc3fc9a27366281.
Report an issue: GitHub.