Docker Error Guide: 'cannot find cgroup mount destination: unknown' — Fix cgroup Mounts
Fix 'cannot find cgroup mount destination: unknown' in Docker: mount the cgroup hierarchy, resolve cgroup v1/v2 mismatches inside privileged and DinD containers, and restart the daemon.
- #docker
- #troubleshooting
- #errors
- #cgroups
Stuck on this Docker with AI error? Get the free incident triage checklist
A one-page PDF — the exact steps to isolate, fix, and verify a production error like this one. No spam, unsubscribe anytime.
Overview
cannot find cgroup mount destination: unknown means runc tried to set up a container’s control-group (cgroup) hierarchy but could not find the expected cgroup filesystem mounted where it looked. cgroups are how Linux enforces CPU, memory, and PID limits, so when the mount is missing or laid out differently than runc expects, container creation fails outright. The literal error appears when starting a container:
docker: Error response from daemon: OCI runtime create failed: container_linux.go:380: starting container process caused: process_linux.go:545: container init caused: cannot find cgroup mount destination: unknown.
It shows up most often inside minimal or nested environments — Docker-in-Docker, systemd-nspawn, WSL, or slim base images used as a host — where the /sys/fs/cgroup hierarchy was never fully mounted, or where a cgroup v1 vs v2 mismatch confuses runc.
Symptoms
docker runfails immediately withOCI runtime create failed: ... cannot find cgroup mount destination: unknown.- The failure only happens inside a privileged “outer” container running Docker-in-Docker (DinD).
- Containers fail to start after upgrading the host kernel/distro to unified cgroup v2, or after switching a runtime.
docker infowarns about cgroup driver or version, and no container will start.- On WSL2 or a stripped-down VM, Docker starts but every
docker rundies with this message.
Common Root Causes
- cgroup hierarchy not mounted — inside a nested or minimal environment
/sys/fs/cgroupis empty or partially mounted, so runc has no destination. - cgroup v1/v2 mismatch — the host runs unified cgroup v2 but the daemon/runtime or a DinD image expects the v1 layout (or vice versa).
- Docker-in-Docker without cgroup access — the outer container was not started with the cgroup mount and privileges the inner daemon needs.
- Missing
--cgroupnshandling — the runtime and daemon disagree on the cgroup namespace mode for the container. - Broken or partial
/sys/fs/cgroupremount — a manual mount, a custom init, or a non-systemd PID 1 left the controller mounts incomplete. - Outdated runc/containerd — an old runtime that predates full cgroup v2 support running on a v2-only host.
Diagnostic Workflow
First determine which cgroup version and driver the daemon is using:
docker info | grep -i cgroup # Cgroup Version and Cgroup Driver
Confirm what the kernel actually has mounted — this is the crux of the error:
mount | grep cgroup
stat -fc %T /sys/fs/cgroup # 'cgroup2fs' = v2 unified; 'tmpfs' = v1 hierarchy
ls /sys/fs/cgroup # v1 shows controller subdirs (cpu, memory...); v2 shows cgroup.controllers
Check whether the host booted with unified cgroups and read the daemon logs for the failure:
cat /proc/cmdline | tr ' ' '\n' | grep -i cgroup # systemd.unified_cgroup_hierarchy=...
journalctl -u docker --since '15 min ago' | grep -i 'cgroup\|oci runtime'
If this is Docker-in-Docker, inspect how the outer container was launched:
docker inspect <outer-container> --format '{{.HostConfig.Privileged}} {{json .Mounts}}'
Verify the runtime version, since old runc lacks full v2 support:
docker info | grep -i 'runtime\|containerd'
runc --version
Example Root Cause Analysis
A CI pipeline that built images inside a Docker-in-Docker service container started failing every inner docker run with cannot find cgroup mount destination: unknown after the CI provider upgraded its host image to a cgroup v2-only kernel. docker info on the host showed Cgroup Version: 2, but the DinD image in use shipped an older runc that assumed the v1 layout. Inside the outer container, stat -fc %T /sys/fs/cgroup returned cgroup2fs, yet the inner daemon looked for the v1 controller subdirectories that did not exist — hence “cannot find cgroup mount destination.” The fix was two-fold: upgrade the DinD image to a version whose runc/containerd fully support cgroup v2, and ensure the outer container was started --privileged with /sys/fs/cgroup available. After that, the inner daemon found the unified hierarchy and containers started cleanly. Root cause: a cgroup v1-era runtime running against a v2-only host, not a host misconfiguration.
Prevention Best Practices
- Keep runc, containerd, and the Docker Engine current so they fully support the host’s cgroup version (v2 is now the default on modern distros).
- Match Docker-in-Docker image versions to the host’s cgroup version; pin a DinD tag that is known-good for cgroup v2.
- Run DinD outer containers
--privileged(or with the explicit cgroup mount) so the inner daemon can manage cgroups. - Standardize on cgroup v2 across a fleet rather than mixing v1 and v2 hosts, to avoid runtime mismatch surprises.
- After a kernel/distro upgrade, re-check
docker infocgroup version and smoke-testdocker run hello-worldbefore promoting the image. - Avoid non-systemd, hand-rolled init in “host” containers unless you deliberately mount the full cgroup hierarchy.
Quick Command Reference
docker info | grep -i cgroup # daemon cgroup version + driver
mount | grep cgroup # what is actually mounted
stat -fc %T /sys/fs/cgroup # cgroup2fs (v2) vs tmpfs (v1)
ls /sys/fs/cgroup # controller layout
cat /proc/cmdline | tr ' ' '\n' | grep cgroup # unified hierarchy boot flag
runc --version # runtime cgroup v2 support
journalctl -u docker --since '15 min ago' | grep -i cgroup
docker run --rm hello-world # smoke test after a fix
Conclusion
cannot find cgroup mount destination: unknown is almost always a mismatch between where runc expects the cgroup hierarchy and where it actually is — usually a cgroup v1-era runtime meeting a v2-only host, or a nested/minimal environment where /sys/fs/cgroup was never fully mounted. Start by comparing docker info’s reported cgroup version against stat -fc %T /sys/fs/cgroup, then reconcile them by upgrading runc/containerd, matching your Docker-in-Docker image to the host’s cgroup version, and ensuring the outer container has privileged access to the cgroup mount. More runtime and OCI-layer fixes are in the Docker guides.
Fixed it? Get 500 Docker with AI & DevOps AI prompts — free
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.
Stuck on this? Start guided troubleshooting
Open an interactive diagnostic session with this error already loaded. Work a step-by-step plan, record what each check returns, land on a root cause, and export a clean incident summary — no account needed to start.
Did this fix your issue?
Solved it a different way?
Share the fix that worked for you — reviewed, then published to help the next engineer.
That looks like it may contain a secret (key, token, password, or connection string). Please remove it — a note with a detected secret can’t be published.
Thanks — that helps. Published notes appear after a quick review.
Trending errors this week
The error guides other engineers are actually reading right now.
- 1mount: wrong fs type, bad option, bad superblock
- 2Docker 'failed to set up container networking': Fix the Bridge and IP Pool
- 3Docker 'failed to create shim task': How to Fix the containerd Runtime Error
- 4Transport endpoint is not connected
- 5modprobe: FATAL: Module not found
- 6mount: wrong fs type, bad option, bad superblock
Get 500 Battle-Tested DevOps AI Prompts — Free
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.