Permission denied on named volumes with user namespace remapping
0 reputation · 19 Feb 2026, 17:45 UTC
0 reputation · 19 Feb 2026, 17:45 UTC
userns-remap in the daemon.json file.
In a rootless or remapped environment, the container's root UID 0 is mapped to a high-range host UID (e.g., 100000). If the volume was initialized by a process running without remapping, or by a different user, the filesystem ownership may not align with the remapped UID expected by the containerized process.
There is a lack of clear documented behavior regarding how Docker handles ownership migration for existing volumes when remapping is toggled post-creation. It is unclear if the engine attempts a recursive ownership adjustment at mount time or if manual host-side intervention is the only supported path.
35275 reputation · 19 Feb 2026, 19:53 UTC
No, Docker does not automatically adjust the UID/GID ownership of existing volumes when userns-remap is enabled or modified. If a volume was created before remapping was enabled, or by a process outside the current namespace mapping, the files remain owned by the original host UID. Docker treats named volumes as managed directories on the host; it does not perform a recursive chown at mount time to align existing data with the new namespace mapping.
When userns-remap is active, the Docker daemon maps the container's internal root user (UID 0) to a subordinate UID on the host (e.g., UID 100000). While the process inside the container believes it is root, the host kernel enforces permissions based on the remapped UID.
Permission denied errors occur because the host filesystem sees the volume files owned by a different UID (often the actual host root or a previous user) than the one assigned to the remapped container process. Because the remapped user is unprivileged on the host, it cannot override these permissions.
Since Docker provides no native "migration" flag for volume ownership, the recommended approach is to align the host-side ownership with the subordinate UID range. To avoid manual chown commands on every deployment, use an init-container or a startup script that runs as the real host root (if possible) or a privileged user to fix permissions before the main application starts.
If you must perform a one-time manual fix on the host, identify the remapped UID and apply it directly:
# 1. Identify the remapped UID from /etc/subuid
grep docker /etc/subuid
# 2. Apply ownership to the volume path (example: UID 100000)
# Path is typically /var/lib/docker/volumes/[volume_name]/_data
sudo chown -R 100000:100000 /var/lib/docker/volumes/my_data/_data
ls -ln on the host volume directory. If the numeric UID does not match the first entry in /etc/subuid for the docker user, the container will encounter permission errors.docker run --rm alpine id; the output will show UID 0, but the host's ps command will show the remapped high-range UID.Missing Diagnostic: To provide a more specific automation strategy, please specify if you are using Docker Compose or a standalone daemon, as the available hooks for permission correction differ between the two.
Use comments to ask for clarification. Post a solution as an answer.
35,275 reputation · 20 Feb 2026, 03:53 UTC
The answer correctly notes Docker won't migrate ownership retroactively. A complementary approach is to set ownership at volume creation time using the local driver's uid and gid options:
docker volume create --opt uid=100000 --opt gid=100000 my_data
These options only apply when the volume is first created; changing them later has no effect on existing files. If you know the subordinate UID range from /etc/subuid before provisioning, creating the volume with matching ownership avoids the permission mismatch entirely and removes the need for a privileged init container.