containerd/containerd · error

failed to get spec: %w

Error message

failed to get spec: %w

What it means

updateContainerIOOwner (Linux, user-namespace support) fetches the container's OCI runtime spec via cntr.Spec(ctx) to compute uid/gid mappings for task I/O ownership. If the spec cannot be retrieved from containerd's services, the error is wrapped and returned. This only runs when a user namespace mode other than NODE is requested.

Source

Thrown at internal/cri/server/container_start_linux.go:52

	// FIXME(fuweid):
	//
	// For builtin runc runtime, the pipe owner should be aligned with process
	// owner. No matter what user namespace container uses, it should work
	// well.
	//
	// However, gVisor runtime doesn't support runc.Options and no idea why
	// adding options could breaks the sig-node conformance case [when querying /stats/summary should report resource usage through the stats api].
	// In order to keep compatible, the change should apply to user namespace only.
	//
	// REF: https://github.com/containerd/containerd/issues/11091
	usernsOpts := config.GetLinux().GetSecurityContext().GetNamespaceOptions().GetUsernsOptions()
	if usernsOpts == nil || usernsOpts.Mode == runtime.NamespaceMode_NODE {
		return nil, nil
	}

	spec, err := cntr.Spec(ctx)
	if err != nil {
		return nil, fmt.Errorf("failed to get spec: %w", err)
	}

	if spec.Linux == nil || spec.Process == nil {
		return nil, fmt.Errorf("invalid linux platform oci runtime spec")
	}

	idMap := userns.IDMap{
		UidMap: spec.Linux.UIDMappings,
		GidMap: spec.Linux.GIDMappings,
	}
	hostID, err := idMap.ToHost(userns.User{
		Uid: spec.Process.User.UID,
		Gid: spec.Process.User.GID,
	})
	if err != nil {
		return nil, fmt.Errorf("failed to do idmap to get host ID: %w", err)
	}

View on GitHub (pinned to 4246446a2b)

Solutions

  1. Confirm the container still exists (`crictl inspect <id>`) and re-run the start
  2. Check containerd logs for spec/blob store errors
  3. If userns support is not needed, set namespace mode to NODE to bypass this path
  4. Upgrade containerd if the spec store is known-buggy in your version

Example fix

// before: start with userns POD mode unconditionally
// after: validate spec availability first
status, _ := runtimeService.ContainerStatus(id)
if usesUserNamespace(status) {
    if _, err := fetchSpec(id); err != nil { // caller-side health probe
        return fmt.Errorf("spec unavailable for userns container: %w", err)
    }
}
return runtimeService.StartContainer(id)
Defensive patterns

Strategy: try-catch

Validate before calling

// only relevant when userns mode != NODE
if usernsMode != runtime.NamespaceMode_NODE {
    if !containerExists(id) { return fmt.Errorf("container %s gone", id) }
}

Try / catch

err := startContainer(id)
if errors.Is(err, ErrContainerNotFound) || errors.Is(err, grpcNotFound(err)) {
    // container was removed concurrently: recreate
}

Prevention

When it happens

Trigger: Calling StartContainer on a container configured with user-namespace mode (e.g. POD or custom userns) while the container's spec cannot be loaded from containerd (container deleted concurrently, containerd store issue, or snapshot/content corruption).

Common situations: Using Kubernetes user namespaces (UserNamespaces feature) or rootless configurations; container removed between lookup and spec fetch; containerd restart mid-operation leaving stale references.

Related errors


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