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
- Confirm the container still exists (`crictl inspect <id>`) and re-run the start
- Check containerd logs for spec/blob store errors
- If userns support is not needed, set namespace mode to NODE to bypass this path
- 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
- Avoid racing removal against start for userns containers
- Keep containerd and shims up to date when using user namespaces
- Use NODE namespace mode unless userns is explicitly required
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
- invalid linux platform oci runtime spec
- failed to do idmap to get host ID: %w
- unprivileged_icmp and unprivileged_port require kernel versi
- check current system kernel version error: %w
- rootfs-propagation %q must be empty or one of (r)private|(r)
AI-assisted analysis of containerd/containerd@4246446a2b (2026-09-02).
Data as JSON: /api/errors/06bad0e8c87fd8fc.
Report an issue: GitHub.