containerd/containerd · error

failed to find runtime handler %q

Error message

failed to find runtime handler %q

What it means

createContainer looks up the sandbox's runtime handler in the in-memory map c.runtimeHandlers (populated from containerd's CRI runtimes configuration). If the handler string stored on the sandbox (r.sandboxRuntimeHandler) is not a configured handler key, creation fails with 'failed to find runtime handler'. Unlike the sandbox-runtime error, this one is specifically about the handler registry map.

Source

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

	}

	// 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 {
		return "", fmt.Errorf("failed to find runtime handler %q", r.sandboxRuntimeHandler)
	}
	log.G(r.ctx).Debugf("Use OCI runtime %+v for sandbox %q and container %q", ociRuntime, r.sandboxID, r.containerID)

	imageName := (*r.containerdImage).Name()
	if name := r.containerConfig.GetImage().GetUserSpecifiedImage(); name != "" {
		imageName = name
	}

	spec, err := c.buildContainerSpec(
		platform,
		r.containerID,
		r.sandboxID,
		r.sandboxPid,
		r.NetNSPath,
		r.containerName,
		imageName,
		r.containerConfig,
		r.podSandboxConfig,

View on GitHub (pinned to 4246446a2b)

Solutions

  1. Run containerd config dump | grep runtimes to list configured handlers and confirm the exact handler name
  2. Add the missing handler section to /etc/containerd/config.toml and restart containerd
  3. Correct the Kubernetes RuntimeClass/handler name so it matches a configured handler exactly (case-sensitive)
  4. Recreate the sandbox: sandboxes pin their handler at creation, so an existing pod keeps the stale name

Example fix

// before — RuntimeClass handler 'kata' not in containerd config
kind: RuntimeClass
handler: kata
// after — either configure handler 'kata' in config.toml or use an existing one
kind: RuntimeClass
handler: runc
Defensive patterns

Strategy: validation

Validate before calling

// Pre-check the handler exists before scheduling/creating
const { stdout } = await exec('containerd config dump');
const handlers = [...stdout.matchAll(/runtimes\.([\w.-]+)/g)].map(m => m[1]);
if (!handlers.includes(sandboxRuntimeHandler)) {
  throw new Error(`handler '${sandboxRuntimeHandler}' not configured; have: ${handlers.join(',')}`);
}

Type guard

function isRuntimeHandlerNotFoundError(err) {
  return err instanceof Error &&
    /failed to find runtime handler "[^"]+"/.test(err.message);
}

Try / catch

try {
  await criClient.createContainer(sandboxId, cfg);
} catch (err) {
  if (isRuntimeHandlerNotFoundError(err)) {
    const handler = err.message.match(/"([^"]+)"/)?.[1];
    throw new HandlerNotConfiguredError(handler, err); // route to a node with that handler configured
  }
  throw err;
}

Prevention

When it happens

Trigger: r.sandboxRuntimeHandler references a handler absent from config.toml's runtimes table; the default runtime handler was renamed in config after the sandbox was created; containerd config failed to load runtimes (malformed TOML section) leaving the map missing entries.

Common situations: RuntimeClass in Kubernetes naming a handler ('kata-qemu') not configured in containerd; typo in the runtimes table key; containerd started with a generated config (k3s/kubeadm) that dropped custom runtimes; case-sensitivity mismatch in handler names.

Related errors


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