How to fix cannot open '/etc/passwd': Permission denied in Docker

DockerINTERMEDIATEMEDIUMUpdated Dec 6, 2025· 262 views

The 'cannot open: Permission denied' error occurs when a process inside a Docker container cannot read or write to system files like /etc/passwd. This typically happens due to user namespace remapping, read-only filesystem mounts, SELinux policies, or running commands that require root privileges as a non-root user.

Quick fix

Fixes EACCES

# Check current user
docker exec <container_name> whoami

# Run command as root
docker exec -u root <container_name> useradd newuser

# Or enter an interactive shell as root
docker exec -u 0 -it <container_name> /bin/sh
  1. Run the command as root inside the container
  2. Avoid mounting /etc/passwd from the host
  3. Handle rootless Docker and Podman user namespaces
  4. Fix SELinux blocking file access
docker — error
# Check current user
docker exec <container_name> whoami
# Run command as root
docker exec -u root <container_name> useradd newuser
# Or enter an interactive shell as root
docker exec -u 0 -it <container_name> /bin/sh
cannot open '/etc/passwd': Permission denied

What this error means

The "cannot open '/etc/passwd': Permission denied" error indicates that a process inside your Docker container is trying to access the /etc/passwd file (or similar system files) but lacks the necessary permissions. This error commonly occurs in these scenarios: - Commands like `useradd`, `usermod`, `groupadd`, or `passwd` need to modify /etc/passwd but the container runs as a non-root user - You've mounted /etc/passwd from the host into the container, and the mount prevents modifications - SELinux or AppArmor security policies are blocking access to the file - Rootless Docker mode uses user namespace remapping that changes effective permissions - The container's filesystem is mounted read-only or with restricted capabilities The error is particularly common in CI/CD pipelines, containers that dynamically create users at runtime, and setups using rootless Docker or Podman.

Typical symptoms

  • Commands like useradd, usermod, or passwd fail with 'Permission denied'
  • Container entrypoint scripts that modify users fail on startup
  • CI/CD pipelines fail when trying to add users inside containers
  • Application initialization fails when trying to read user information
  • Error message shows 'cannot lock /etc/passwd' or 'cannot open /etc/passwd'
  • Same container works on one machine but fails on another (rootless vs rootful)

Common causes

  1. Running user modification commands as a non-root user in the container
  2. Mounting /etc/passwd or /etc/shadow from the host as a read-only volume
  3. User namespace remapping in rootless Docker or Podman mode
  4. SELinux or AppArmor policies blocking access to system files
  5. Container running with --read-only flag or read-only root filesystem
  6. Using a distroless or minimal base image without proper user utilities

How to fix "cannot open '/etc/passwd': Permission denied"

1Run the command as root inside the container

If you need to run user management commands, ensure you're running as root:

bash
# Check current user
docker exec <container_name> whoami

# Run command as root
docker exec -u root <container_name> useradd newuser

# Or enter an interactive shell as root
docker exec -u 0 -it <container_name> /bin/sh

In your Dockerfile, perform user operations before switching to a non-root user:

dockerfile
FROM ubuntu:22.04

# Run user operations as root (default)
RUN useradd -m appuser

# Then switch to non-root user
USER appuser

CMD ["./app"]
2Avoid mounting /etc/passwd from the host

If you've mounted /etc/passwd or /etc/shadow from the host, user modification commands will fail because mount points cannot be replaced:

bash
# This causes problems:
docker run -v /etc/passwd:/etc/passwd:ro myimage

# The passwd command creates a temp file and tries to rename it,
# which fails on a mount point

Solutions:

1. Don't mount individual files - mount a directory instead if needed:

bash
docker run -v /etc:/etc myimage

2. Create users in the Dockerfile instead of at runtime:

dockerfile
RUN useradd -u 1000 -m appuser

3. Use NSS (Name Service Switch) for user mapping instead of mounting passwd files:

bash
# Use libnss-extrausers or similar for dynamic user databases
3Handle rootless Docker and Podman user namespaces

Rootless Docker and Podman use user namespaces that remap UIDs/GIDs, which can cause permission issues:

bash
# Check if you're running rootless Docker
docker info | grep -i rootless

# Check user namespace mappings
cat /etc/subuid
cat /etc/subgid

Solutions for rootless mode:

1. Use --userns=host to disable user namespace for a container:

bash
docker run --userns=host myimage
# Note: This reduces security isolation

2. Ensure proper subuid/subgid configuration:

bash
# Check your user has enough subordinate UIDs
grep $USER /etc/subuid
# Should show: username:100000:65536 (or similar)

# If missing, add them:
sudo usermod --add-subuids 100000-165535 --add-subgids 100000-165535 $USER

3. For Podman, use the :U volume option:

bash
podman run -v ./data:/app/data:U myimage
# :U tells Podman to chown the volume to match the container user
4Fix SELinux blocking file access

SELinux may block container access to certain files. Check if SELinux is the cause:

bash
# Check SELinux status
getenforce

# Check for SELinux denials
sudo ausearch -m avc -ts recent
# Or check the audit log
sudo grep denied /var/log/audit/audit.log | tail

Solutions:

1. Add the :z or :Z flag to volume mounts:

bash
# :z allows the volume to be shared between containers
docker run -v ./data:/app/data:z myimage

# :Z makes the volume private to this container
docker run -v ./data:/app/data:Z myimage

2. Use the container_file_t context:

bash
sudo chcon -Rt svirt_sandbox_file_t /path/to/volume

3. Create an SELinux policy exception (less recommended):

bash
# Generate a policy module from denials
sudo ausearch -m avc -ts recent | audit2allow -M mycontainer
sudo semodule -i mycontainer.pp
5Remove read-only filesystem restrictions

If your container uses a read-only root filesystem, /etc/passwd cannot be modified:

bash
# Check if filesystem is read-only
docker inspect <container> | grep -A5 ReadonlyRootfs

Solutions:

1. Mount /etc as a tmpfs for runtime modifications:

bash
docker run --read-only --tmpfs /etc myimage

2. Or mount specific files as writable volumes:

bash
docker run --read-only \
  -v passwd-data:/etc/passwd \
  -v shadow-data:/etc/shadow \
  myimage

3. Create users in the Dockerfile before setting read-only:

dockerfile
FROM alpine

# Create all users while filesystem is writable
RUN adduser -D appuser

# Application can run read-only since users exist
USER appuser
CMD ["./app"]
6Match container UID with host UID for bind mounts

When using bind mounts, ensure the container user has matching permissions:

bash
# Find your host user's UID/GID
id -u  # e.g., 1000
id -g  # e.g., 1000

Build the container with matching UID:

dockerfile
FROM node:20

# Create user with specific UID matching host user
ARG UID=1000
ARG GID=1000

RUN groupadd -g $GID appgroup \
    && useradd -u $UID -g appgroup -m appuser

USER appuser

Build and run with matching IDs:

bash
# Build with your UID/GID
docker build --build-arg UID=$(id -u) --build-arg GID=$(id -g) -t myapp .

# Or pass at runtime
docker run --user $(id -u):$(id -g) myapp
7Verify the fix

After applying fixes, verify that file access works:

bash
# Test reading /etc/passwd
docker exec <container> cat /etc/passwd

# Test user lookup
docker exec <container> id
docker exec <container> whoami

# Test user modification (if needed)
docker exec -u root <container> useradd testuser
docker exec <container> grep testuser /etc/passwd

# For volume mounts, test file creation
docker exec <container> touch /app/data/testfile

If using CI/CD, ensure your pipeline logs show successful execution without permission errors.

Advanced notes

Understanding /etc/passwd in Containers

The /etc/passwd file maps usernames to numeric UIDs. When you run a container, Linux kernel permission checks use numeric UIDs, not usernames. The container has its own /etc/passwd that's independent from the host's file.

Commands like useradd work by:
1. Creating a temporary file
2. Writing the new passwd data
3. Renaming the temp file to /etc/passwd

This rename fails if /etc/passwd is a mount point (individual file mount) rather than a regular file.

Rootless Docker vs Rootful Docker

In rootful Docker, UID 0 inside the container is UID 0 on the host (real root). In rootless Docker, UID 0 inside the container maps to your unprivileged host UID (e.g., 1000). This is more secure but causes permission mismatches.

Check your mode:

bash
# Rootless shows your user's home path
docker info | grep "Docker Root Dir"
# Rootless: /home/user/.local/share/docker
# Rootful: /var/lib/docker

User Namespace Mapping

With user namespaces, container UIDs are mapped to different host UIDs:
- Container UID 0 -> Host UID 100000 (example)
- Container UID 1000 -> Host UID 101000

This mapping is defined in /etc/subuid and /etc/subgid.

Security Considerations

Avoid these insecure workarounds:
- Running containers with --privileged just to fix permission issues
- Disabling SELinux (setenforce 0) instead of fixing policies
- Using chmod 777 on host directories

Instead, properly configure user mappings and security contexts.

Container Runtimes Comparison

| Runtime | User Namespace | SELinux Support | Notes |
|---------|---------------|-----------------|-------|
| Docker (rootful) | Optional | Yes | Traditional mode |
| Docker (rootless) | Always | Limited | More secure, more complex |
| Podman | Default | Yes | :U and :Z options |
| Containerd | Configurable | Yes | Lower-level runtime |

CI/CD Specific Issues

CI/CD systems often use restricted container runtimes. If you encounter this error in CI:
1. Check if the CI system uses rootless containers
2. Avoid runtime user creation; create users in Dockerfile
3. Use docker-in-docker (dind) carefully with proper volume mounts

Frequently asked questions

What does "EACCES" mean?
The "cannot open '/etc/passwd': Permission denied" error indicates that a process inside your Docker container is trying to access the /etc/passwd file (or similar system files) but lacks the necessary permissions. This error commonly occurs in these scenarios: - Commands like useradd, usermod, groupadd, or passwd need to modify /etc/passwd but the container runs as a non-root user - You've mounted /etc/passwd from the host into the container, and the mount prevents modifications - SELinux or AppArmor security policies are blocking access to the file - Rootless Docker mode uses user namespace remapping that changes effective permissions - The container's filesystem is mounted read-only or with restricted capabilities The error is particularly common in CI/CD pipelines, containers that dynamically create users at runtime, and setups using rootless Docker or Podman.
How do I fix "EACCES"?
The 'cannot open: Permission denied' error occurs when a process inside a Docker container cannot read or write to system files like /etc/passwd. This typically happens due to user namespace remapping, read-only filesystem mounts, SELinux policies, or running commands that require root privileges as a non-root user.
What causes "EACCES"?
Running user modification commands as a non-root user in the container Mounting /etc/passwd or /etc/shadow from the host as a read-only volume User namespace remapping in rootless Docker or Podman mode
Is the "EACCES" error serious?
It is a medium-severity error — more of a blocker than a risk. The steps above resolve it.

Official resources & further reading