Skip to content
DevOps AI ToolKit
Newsletter
All guides
Docker with AI By James Joyner IV · · 9 min read

Docker Error Guide: 'error mounting to rootfs' — Fix Container Mount Setup

Quick answer

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.

Part of the Docker Container & Runtime Errors hub
  • #docker
  • #troubleshooting
  • #errors
  • #runtime
Free toolkit

Fixing errors like this? Get 500 free DevOps AI prompts

500 copy-paste AI prompts for the stack you actually run — one PDF, free.

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 rootfs and an OCI runtime message.
  • The message ends in not a directory, no such file or directory, permission denied, or read-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/--mount fail; 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: unknown is 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/:Z relabel 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 -v flag silently creates missing sources as directories, causing type mismatches.
  • Use --mount instead of -v so a missing bind source fails loudly rather than being auto-created wrong.
  • Add :z/:Z on 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.

Free download · 368-page PDF

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.