Docker Error Guide: 'error while creating mount source path: operation not permitted' — Share the Path or Fix Ownership
Fix Docker 'error while creating mount source path: operation not permitted' by sharing the path in Docker Desktop File Sharing or fixing Linux host permissions and SELinux.
- #docker
- #troubleshooting
- #errors
- #volumes
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
Docker raises this when you bind-mount a host directory into a container and the daemon cannot create (or access) that source path. On Docker Desktop it almost always means the path is outside the shared filesystem; on Linux it means the daemon lacks permission to create the directory:
docker: Error response from daemon: error while creating mount source path '/host/path': mkdir /host/path: operation not permitted.
The daemon is trying to mkdir the bind-mount source before it can wire it into the container. When that mkdir returns EPERM, the container never starts.
Symptoms
docker run -v /host/path:/data ...(ordocker compose up) fails immediately withoperation not permitted.- The same command works for a path under your home directory but fails for another location.
- On macOS/Windows Docker Desktop, the failing path is outside the configured shared folders.
- On Linux,
ls /host/pathmay not exist yet, and the daemon (often rootless or SELinux-confined) cannot create it. - Named volumes work fine; only bind mounts of specific host paths fail.
Common Root Causes
- Docker Desktop file sharing (macOS/Windows) — the host path is not in Settings > Resources > File Sharing, so the VM’s daemon cannot reach it and its attempt to create the mount source is denied.
- Nonexistent parent on a protected filesystem — the source path does not exist and its parent directory is not writable by the daemon user.
- Rootless Docker — a rootless daemon runs as your unprivileged user and cannot
mkdirunder root-owned locations like/srv,/opt, or/var. - SELinux / AppArmor confinement — the mandatory-access-control policy blocks the daemon from creating or mounting the path even though POSIX permissions would allow it.
- Host ownership/permissions — the path (or its parent) is owned by a different user with no write bit for the daemon.
- Read-only or special filesystem — the parent lives on a read-only mount, a
noexec/immutable location, or a synthetic filesystem the daemon may not modify.
Diagnostic Workflow
First, confirm exactly which path and operation failed, and whether you are on Docker Desktop or native Linux:
docker info | grep -i 'Operating System\|Docker Root Dir\|rootless'
docker version --format '{{.Server.Os}}/{{.Server.Arch}}'
Check whether the source path exists and who owns it (native Linux):
ls -ld /host /host/path 2>&1
stat -c '%U:%G %a' /host 2>/dev/null
Read the daemon’s own view of the failure:
journalctl -u docker --since '10 min ago' | grep -i 'mount source\|operation not permitted\|permission'
On Docker Desktop, verify the shared folders. The path must be under a directory listed here:
Docker Desktop > Settings > Resources > File Sharing
/Users
/Volumes
/private
/tmp
If SELinux is enforcing, check for denials:
getenforce
sudo ausearch -m avc -ts recent | grep -i docker
For rootless setups, confirm the daemon’s UID and whether it owns the target:
docker context inspect --format '{{.Endpoints.docker.Host}}'
id
Example Root Cause Analysis
A developer on macOS ran a database container mapping a project data directory that lived outside their home folder:
docker run -d -v /data/pg:/var/lib/postgresql/data postgres:16
# docker: Error response from daemon: error while creating mount source path
# '/data/pg': mkdir /data/pg: operation not permitted.
docker info showed the server OS was the Docker Desktop Linux VM, and /data was not one of the shared folders. Because the daemon runs inside the VM and only the paths listed under File Sharing are projected into it, the daemon could not create /data/pg. Adding the parent under Settings > Resources > File Sharing (or relocating the data under /Users/<name>/..., which is shared by default) and restarting Docker Desktop resolved it:
mkdir -p ~/project/pg
docker run -d -v ~/project/pg:/var/lib/postgresql/data postgres:16
On a Linux host the same error had a different root cause: the daemon was rootless and the bind source /opt/appdata was root-owned. Pre-creating the directory and giving the rootless user ownership fixed it:
sudo mkdir -p /opt/appdata
sudo chown $(id -u):$(id -g) /opt/appdata
docker run -d -v /opt/appdata:/data alpine sleep 1
Prevention Best Practices
- On Docker Desktop, keep bind-mount sources under an already-shared root (
/Users,/Volumes) or add project roots to File Sharing once, up front. - Pre-create host directories with the correct owner before
docker run, rather than relying on the daemon tomkdirthem. - Prefer named volumes over bind mounts for service data; the daemon manages their storage and never hits host-permission issues.
- For rootless Docker, keep bind sources under paths your user owns (typically your home directory).
- On SELinux hosts, add the
:z/:Zmount option so Docker relabels the volume instead of being denied. - Document required shared folders in your team’s onboarding so new machines are configured consistently.
Quick Command Reference
# What kind of daemon am I talking to?
docker info | grep -i 'Operating System\|rootless'
# Does the source exist and who owns it?
ls -ld /host/path && stat -c '%U:%G %a' /host/path
# Pre-create with correct ownership (rootless / host-perms case)
sudo mkdir -p /host/path && sudo chown $(id -u):$(id -g) /host/path
# SELinux: relabel the bind mount so the container may access it
docker run -v /host/path:/data:Z alpine ls /data
# Read the daemon's error
journalctl -u docker --since '10 min ago' | grep -i 'operation not permitted'
# Docker Desktop: add the parent under Settings > Resources > File Sharing, then
# Restart from the whale menu
Conclusion
error while creating mount source path: operation not permitted is a permission failure on the host side of a bind mount, not inside the container. On Docker Desktop the fix is to share the path under Settings > Resources > File Sharing (or move data under an already-shared root). On Linux, pre-create the directory with the right owner, account for rootless daemons, and relabel with :Z when SELinux is enforcing. When in doubt, switch to a named volume and let Docker own the storage.
For related mounting failures, see the invalid mount config for type bind guide, the mounts denied not shared from the host guide, and more fixes in the Docker guides.
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.