containerd/containerd · error

failed to get sandbox controllers from plugins %v

Error message

failed to get sandbox controllers from plugins %v

What it means

The CRI server needs pod-sandbox controllers to manage pods. initCRIService calls getSandboxControllers(ic), which resolves SandboxControllerPlugin instances from the plugin context; on failure (missing controllers or lookup error) this message wraps the cause and the CRI plugin fails to load. Without sandbox controllers the CRI runtime cannot create or stop pod sandboxes.

Source

Thrown at plugins/cri/cri.go:129

		for _, w := range warnings {
			warn.Emit(ic.Context, w)
		}
	}

	log.G(ctx).Info("Connect containerd service")
	client, err := containerd.New(
		"",
		containerd.WithDefaultNamespace(constants.K8sContainerdNamespace),
		containerd.WithDefaultPlatform(platforms.Default()),
		containerd.WithInMemoryServices(ic),
	)
	if err != nil {
		return nil, fmt.Errorf("failed to create containerd client: %w", err)
	}

	sbControllers, err := getSandboxControllers(ic)
	if err != nil {
		return nil, fmt.Errorf("failed to get sandbox controllers from plugins %v", err)
	}

	streamingConfig, err := config.StreamingConfig()
	if err != nil {
		return nil, fmt.Errorf("failed to get streaming config: %w", err)
	}

	var shimPath string
	shimPlugin, err := ic.GetSingle(plugins.ShimPlugin)
	if err != nil {
		return nil, fmt.Errorf("failed to get shim plugin: %w", err)
	}
	if hasEnv, ok := shimPlugin.(interface{ Env() []string }); ok {
		env := hasEnv.Env()
		for i := len(env) - 1; i >= 0; i-- {
			// iterate backwards to grab the last PATH=
			if path, ok := strings.CutPrefix(env[i], "PATH="); ok {
				shimPath = path

View on GitHub (pinned to 4246446a2b)

Solutions

  1. Read the wrapped error from getSandboxControllers to see which controller lookup failed.
  2. Ensure the built-in sandbox controller plugins (e.g. io.containerd.sandbox.controller.podsandbox) are compiled in and not disabled in config.toml.
  3. Verify shim-based controllers (e.g. for kata) have their corresponding shim binaries installed and configured.
  4. Update to a containerd release matching your config schema (sandbox controller APIs changed across 1.7/2.x).

Example fix

# before (controllers disabled)
[plugins."io.containerd.internal.cri".controllers]
  podsandbox = ""

# after (use built-in controller)
[plugins."io.containerd.internal.cri"]
  # default podsandbox controller enabled implicitly
Defensive patterns

Strategy: validation

Validate before calling

// Pre-flight: ensure sandbox controllers are registered
// containerd --version and grep startup log for 'sandbox.controller'
// or: for _, c := range ic.GetByType(plugins.SandboxControllerPlugin) { _ = c } // must be non-empty

Try / catch

controllers, err := getSandboxControllers(ic)
if err != nil {
	if errors.Is(err, plugin.ErrPluginNotFound) {
		log.Errorf("no sandbox controller plugins registered; check build/config: %v", err)
	}
	return err
}

Prevention

When it happens

Trigger: containerd startup where no io.containerd.runtime.sandbox.controllers.* plugins resolve — the sandbox controller plugins are absent, disabled, or failed their own initialization (wrapped cause contains the details).

Common situations: Builds compiled without the default sandbox controllers (e.g. "podsandbox" controller); config disabling the controllers section; failure of underlying store services the controllers depend on; version mismatch where the controller plugin type/IDs changed.

Related errors


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