Docker Error Guide: 'error mounting to rootfs' — Fix Container Mount Setup
Fix Docker 'error mounting to rootfs': resolve missing bind sources, file-vs-directory mismatches, SELinux labels, and read-only paths so the OCI runtime can set up container mounts and start.
- #docker
- #troubleshooting
- #errors
- #runtime
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
error mounting to rootfs is raised by the OCI runtime (runc) while it assembles the container’s root filesystem and applies bind mounts, before the entrypoint ever runs. The container’s spec parsed fine, but when runc tried to actually mount a source path onto a target inside the new root, the kernel refused — usually because the source is missing, the source/target types disagree (file vs directory), SELinux blocks it, or the target path is read-only.
The literal error names the target inside rootfs:
docker: Error response from daemon: failed to create task for container: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: error during container init: error mounting "/host/config.yaml" to rootfs at "/etc/app/config.yaml": mount /host/config.yaml:/etc/app/config.yaml (via /proc/self/fd/6), flags: 0x5000: not a directory: unknown.
Symptoms
- Container creation fails immediately with
error mounting ... to rootfsand an OCI runtime message. - The message ends in
not a directory,no such file or directory,permission denied, orread-only file system. - A bind mount that worked before starts failing after the host source was deleted or changed from a file to a directory (or vice versa).
- Only containers with a specific
-v/--mountfail; removing that mount lets the container start.
Common Root Causes
- File-vs-directory mismatch — bind-mounting a host file onto a container directory (or a directory onto a file).
not a directory/not a directory: unknownis the tell. - Missing host source — the bind source path does not exist, so Docker creates an empty directory and the type mismatches, or the mount fails with
no such file or directory. - SELinux denial — on RHEL/Fedora, an unlabeled host path is blocked; the mount needs a
:z/:Zrelabel or a policy exception. - Read-only target path — mounting onto a path under a read-only root filesystem or an already read-only mount.
- Target parent missing in image — the destination’s parent directory does not exist in the image and cannot be created.
- Nested/duplicate mount conflict — two mounts targeting overlapping paths in an incompatible order.
Diagnostic Workflow
Read the full runc message — the to rootfs at "<target>" and trailing reason pinpoint the cause:
docker run ... 2>&1 | tail -5
journalctl -u docker --since '5 min ago' | grep -i 'rootfs\|oci runtime'
Verify the host source exists and check its type against the container target’s type:
ls -ld /host/config.yaml # file or directory?
docker run --rm <image> ls -ld /etc/app/config.yaml # what the image has there
If not a directory appears, the source and target types disagree — decide which should be a file.
Check for SELinux on RHEL-family hosts:
getenforce
sudo ausearch -m avc -ts recent | grep -i docker
ls -Z /host/config.yaml
Confirm the target is not on a read-only mount:
docker inspect --format '{{.HostConfig.ReadonlyRootfs}}' <container>
Example Root Cause Analysis
A service failed to start after a config refactor with:
error mounting "/opt/app/config.yaml" to rootfs at "/etc/app/config.yaml" ... not a directory: unknown
ls -ld /opt/app/config.yaml showed the host path was a directory (an earlier docker run had auto-created it as a directory when the real file was missing), while the image expected /etc/app/config.yaml to be a file. runc refused to bind a directory onto a file target.
The fix was to remove the stray auto-created directory and place the actual config.yaml file at the source path, so both sides were files. To prevent recurrence, the team switched to --mount type=bind,source=/opt/app/config.yaml,target=/etc/app/config.yaml, which errors clearly when the source does not exist instead of silently creating an empty directory as -v does.
Prevention Best Practices
- Ensure the host source exists and matches type (file→file, dir→dir) before running; the
-vflag silently creates missing sources as directories, causing type mismatches. - Use
--mountinstead of-vso a missing bind source fails loudly rather than being auto-created wrong. - Add
:z/:Zon SELinux hosts for bind mounts, or set the correct context, so relabeling does not block the mount. - Create destination parents in the image (
RUN mkdir -p) when mounting to nested paths. - Avoid mounting onto read-only roots; mount writable paths as tmpfs or dedicated volumes instead.
- Keep config-file mounts explicit and versioned so a file never gets replaced by a directory by accident.
Quick Command Reference
ls -ld /host/source/path # confirm source type/existence
docker run --rm <image> ls -ld /container/target # confirm target type in image
getenforce; ls -Z /host/source/path # SELinux status + label
sudo ausearch -m avc -ts recent | grep docker # SELinux denials
docker run --mount type=bind,source=/abs/file,target=/etc/app/config.yaml img
docker run -v /abs/dir:/data:Z img # SELinux-relabeled bind
Conclusion
error mounting to rootfs is runc failing to set up a bind mount during container init — the spec was valid, the kernel-level mount was not. Read the target path and trailing reason: not a directory means a file/dir type mismatch, no such file means a missing source, and SELinux or read-only targets each have their own tell. Make sources exist with the right type, prefer --mount, and relabel for SELinux. For volume-source mount failures, see the failed to mount local volume guide and the full 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.