containerd/containerd · error

failed to checkpoint container %q: %w

Error message

failed to checkpoint container %q: %w

What it means

Top-level wrapper for CheckpointContainer: the pre-flight CRIU check (checkCriu) failed and the error is logged and wrapped with the container ID. The actual cause (binary missing, version retrieval failure, or too-old version) is in the wrapped chain.

Source

Thrown at internal/cri/server/container_checkpoint_linux.go:149

				return criuPath
			}
		}
		return ""
	}
	if criuPath, err := exec.LookPath("criu"); err == nil {
		if absPath, err := filepath.Abs(criuPath); err == nil {
			return absPath
		}
		return criuPath
	}
	return ""
}

func (c *criService) CheckpointContainer(ctx context.Context, r *runtime.CheckpointContainerRequest) (*runtime.CheckpointContainerResponse, error) {
	start := time.Now()
	if err := c.checkCriu(); err != nil {
		log.G(ctx).WithError(err).Errorf("Failed to checkpoint container %q", r.GetContainerId())
		return nil, fmt.Errorf("failed to checkpoint container %q: %w", r.GetContainerId(), err)
	}

	criContainerStatus, err := c.ContainerStatus(ctx, &runtime.ContainerStatusRequest{
		ContainerId: r.GetContainerId(),
	})
	if err != nil {
		return nil, fmt.Errorf("an error occurred when trying to find container the container status %q: %w", r.GetContainerId(), err)
	}

	container, err := c.containerStore.Get(r.GetContainerId())
	if err != nil {
		return nil, fmt.Errorf("an error occurred when trying to find container %q: %w", r.GetContainerId(), err)
	}

	state := container.Status.Get().State()
	if state != runtime.ContainerState_CONTAINER_RUNNING {
		return nil, fmt.Errorf(
			"container %q is in %s state. only %s containers can be checkpointed",

View on GitHub (pinned to 4246446a2b)

Solutions

  1. Inspect the wrapped cause in the error chain (`errors.Unwrap` or the log line) to see which check failed
  2. Install/repair CRIU on the node and ensure it is on the PATH used by the shim
  3. Confirm CRIU version meets the minimum required by the runtime
  4. Re-run CheckpointContainer after fixing the CRIU installation

Example fix

// before (node without criu)
$ kubectl checkpoint pod/web-0
error: failed to checkpoint container "web": criu binary not found...
// after
$ apt-get install -y criu && criu --version
$ kubectl checkpoint pod/web-0  # succeeds
Defensive patterns

Strategy: try-catch

Validate before calling

path, err := exec.LookPath("criu")
if err != nil {
    return fmt.Errorf("checkpoint unavailable: install criu (>= required version)")
}

Try / catch

_, err := client.CheckpointContainer(ctx, req)
if err != nil {
    var wrapped error = err
    for wrapped != nil {
        if strings.Contains(wrapped.Error(), "criu") {
            // handle missing/broken/old criu
            break
        }
        wrapped = errors.Unwrap(wrapped)
    }
}

Prevention

When it happens

Trigger: Any CheckpointContainer call where the criu binary is absent from both the shim path and system PATH, GetCriuVersion fails, or the version is below utils.PodCriuVersion.

Common situations: CRIU simply not installed on the node; users trying checkpoint on clusters where the feature prerequisite was never set up; after node provisioning without the checkpoint packages; stale shim-local criu.

Related errors


AI-assisted analysis of containerd/containerd@4246446a2b (2026-09-02). Data as JSON: /api/errors/93ae1a10b3aa8d83. Report an issue: GitHub.