containerd/containerd · error

failed to get sandbox runtime: %w

Error message

failed to get sandbox runtime: %w

What it means

createContainer resolves which OCI runtime (runc, kata, etc.) serves the container's pod sandbox via c.getPodSandboxRuntime(r.sandboxID), which maps the sandbox's runtime handler to a configured runtime. If no matching runtime configuration exists or the lookup fails, this error is returned and container creation stops. It is a configuration/resolution error inside containerd's CRI plugin.

Source

Thrown at internal/cri/server/container_create.go:237

	defer func() {
		if retErr != nil {
			// Cleanup the volatile container root directory.
			if err := c.os.RemoveAll(volatileContainerRootDir); err != nil {
				log.G(r.ctx).WithError(err).Errorf(
					"Failed to remove volatile container root directory %q",
					volatileContainerRootDir,
				)
			}
		}
	}()

	platform, err := c.sandboxService.SandboxPlatform(r.ctx, r.sandbox.Sandboxer, r.sandboxID)
	if err != nil {
		return "", fmt.Errorf("failed to query sandbox platform: %w", err)
	}
	ociRuntime, err := c.getPodSandboxRuntime(r.sandboxID)
	if err != nil {
		return "", fmt.Errorf("failed to get sandbox runtime: %w", err)
	}

	// mutate the extra CRI volume mounts from the runtime spec to properly specify the OCI image volume mount requests as bind mounts for this container
	err = c.mutateMounts(r.ctx, r.containerConfig.GetMounts(), c.RuntimeSnapshotter(r.ctx, ociRuntime), r.sandboxID, platform)
	if err != nil {
		return "", fmt.Errorf("failed to mount image volume: %w", err)
	}

	var volumeMounts []*runtime.Mount
	if !c.config.IgnoreImageDefinedVolumes {
		// create a list of image volume mounts from the image spec that are not also already in the runtime config volume list
		volumeMounts = c.volumeMounts(platform, containerRootDir, r.containerConfig, r.imageConfig)
	} else if len(r.imageConfig.Volumes) != 0 {
		log.G(r.ctx).Debugf("Ignoring volumes defined in image %v because IgnoreImageDefinedVolumes is set", r.imageID)
	}

	runtimeHandler, ok := c.runtimeHandlers[r.sandboxRuntimeHandler]
	if !ok {

View on GitHub (pinned to 4246446a2b)

Solutions

  1. Compare the sandbox's runtime handler (crictl inspectp the pod) with the runtimes table in /etc/containerd/config.toml
  2. Add or correct the missing runtime entry and restart containerd (systemctl restart containerd)
  3. If the handler was intentionally removed, delete/recreate the affected pods so new sandboxes use a valid handler
  4. Check containerd logs immediately after this error for the exact handler name that failed to resolve

Example fix

// before — handler missing in config.toml
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
  runtime_type = "io.containerd.runc.v2"
// after — add the handler the sandbox expects
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.kata]
  runtime_type = "io.containerd.runc.v2"
  [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.kata.options]
    BinaryName = "/usr/bin/kata-runtime"
Defensive patterns

Strategy: validation

Validate before calling

// Before rollout, verify every RuntimeClass handler used by pods is configured in containerd
const configured = ['runc', 'kata']; // parse from `containerd config dump`
for (const rc of runtimeClasses) {
  if (!configured.includes(rc.handler)) {
    throw new Error(`RuntimeClass ${rc.name}: handler '${rc.handler}' not in containerd runtimes`);
  }
}

Type guard

function isSandboxRuntimeError(err) {
  return err instanceof Error &&
    String(err.message).includes('failed to get sandbox runtime');
}

Try / catch

try {
  await criClient.createContainer(sandboxId, cfg);
} catch (err) {
  if (isSandboxRuntimeError(err)) {
    throw new ConfigMismatchError('sandbox runtime handler not resolvable to configured runtime — fix /etc/containerd/config.toml runtimes table', err);
  }
  throw err;
}

Prevention

When it happens

Trigger: The sandbox's runtime handler is not present in the [plugins."io.containerd.grpc.v1.cri".containerd.runtimes] table; sandbox metadata is missing or its RuntimeHandler field is empty/mismatched; a CRI RuntimeHandler registered at pod time was removed from config before container create.

Common situations: Kubelet runtimeRequestHandler / RuntimeClass referencing a handler name that differs in spelling from containerd config; config.toml edited (handler renamed/removed) and containerd reloaded while pods still reference the old handler; typo like 'kata-containers' vs 'kata'.

Related errors


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