How to fix exec user process caused: permission denied in Docker

DockerINTERMEDIATEMEDIUMUpdated Dec 6, 2025ยท 312 views

This error occurs when Docker cannot execute the entrypoint script or binary, typically because the file lacks execute permissions, has Windows line endings (CRLF), or SELinux is blocking execution. The fix usually involves adding chmod +x or converting line endings.

Quick fix

Fixes exec user process caused: permission denied

COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
  1. Add execute permission in your Dockerfile
  2. Fix Windows line endings (CRLF to LF)
  3. Verify the shebang line is correct
  4. Set permissions on the host before building
docker โ€” error
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
exec user process caused: permission denied

What this error means

When a Docker container starts, it attempts to execute the command or script specified in the `ENTRYPOINT` or `CMD` instruction. The "exec user process caused: permission denied" error occurs when the Linux kernel cannot execute that file. This happens at the `execve()` system call level, before your script even starts running. The most common causes are: 1. **Missing execute permission**: The file doesn't have the executable bit set (`+x`). Docker copies file permissions from the build context, so if your entrypoint script isn't executable on your host machine, it won't be executable in the container. 2. **Windows line endings (CRLF)**: If the script was created or edited on Windows, it may have carriage return characters (`\r`) at the end of each line. This corrupts the shebang line (e.g., `#!/bin/bash\r`), making the interpreter path invalid. 3. **SELinux restrictions**: On systems with SELinux enabled (CentOS, RHEL, Fedora), the security context may prevent execution even if file permissions are correct. This error is particularly common in CI/CD pipelines where scripts are checked into Git on Windows and built on Linux, or when using the Alpine base image which has a minimal shell environment.

Typical symptoms

  • Container fails immediately on startup with 'exec user process caused: permission denied'
  • The full error message often includes 'standard_init_linux.go' with a line number
  • docker run exits with code 126 or 1
  • The same Dockerfile works on some machines but fails on others (often Windows vs Linux)
  • Container worked before but fails after editing the entrypoint script on Windows
  • docker logs shows nothing because the container never starts

Common causes

  1. Entrypoint script lacks execute permission (+x) in the Docker image
  2. Script has Windows line endings (CRLF) that corrupt the shebang line
  3. Missing or invalid shebang line at the start of the script
  4. Shebang points to an interpreter that doesn't exist in the container (e.g., /bin/bash in Alpine)
  5. SELinux is blocking execution on CentOS/RHEL/Fedora hosts
  6. Filesystem mounted with noexec option where Docker stores images
  7. Binary compiled for wrong architecture (though this usually shows 'exec format error')

How to fix "exec user process caused: permission denied"

1Add execute permission in your Dockerfile

The most common fix is to explicitly set execute permissions in your Dockerfile after copying the script:

dockerfile
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]

If you're copying multiple scripts:

dockerfile
COPY scripts/ /scripts/
RUN chmod +x /scripts/*.sh

Important: Always use the exec form (JSON array) for ENTRYPOINT, not the shell form.

2Fix Windows line endings (CRLF to LF)

If you edited the script on Windows, convert line endings in your Dockerfile:

dockerfile
COPY entrypoint.sh /entrypoint.sh
RUN sed -i 's/\r$//' /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]

Or install and use dos2unix:

dockerfile
RUN apt-get update && apt-get install -y dos2unix
COPY entrypoint.sh /entrypoint.sh
RUN dos2unix /entrypoint.sh && chmod +x /entrypoint.sh

Better long-term fix: Configure Git to preserve LF endings for shell scripts by adding a .gitattributes file:

bash
*.sh text eol=lf
3Verify the shebang line is correct

Ensure your script starts with a valid shebang on the very first line:

bash
#!/bin/bash
# or for Alpine/minimal images:
#!/bin/sh
# or for maximum portability:
#!/usr/bin/env sh

Common mistakes:
- Shebang not on line 1 (blank line or BOM before it)
- Wrong interpreter path (/bin/bash doesn't exist in Alpine, use /bin/sh)
- Invisible characters before the #

Check for hidden characters:

bash
head -1 entrypoint.sh | cat -A

You should see exactly #!/bin/bash$ (or similar). Any ^M indicates CRLF line endings.

4Set permissions on the host before building

Docker's COPY instruction preserves file permissions from your build context. Fix permissions on your host machine:

bash
chmod +x entrypoint.sh
docker build -t myimage .

This is simpler than adding RUN chmod in your Dockerfile, but requires remembering to set permissions before each build (or committing the executable bit to Git).

Verify the file is executable:

bash
ls -la entrypoint.sh
# Should show: -rwxr-xr-x (the x's indicate execute permission)
5Use sh to run the script as a workaround

If you can't modify the Dockerfile or need a quick workaround, explicitly invoke the shell:

dockerfile
ENTRYPOINT ["sh", "/entrypoint.sh"]
# or
ENTRYPOINT ["/bin/sh", "-c", "/entrypoint.sh"]

Or override at runtime:

bash
docker run myimage sh /entrypoint.sh

This bypasses the execute permission check since sh reads and interprets the file rather than executing it directly. However, this is a workaround, not a proper fix.

6Handle SELinux on CentOS/RHEL/Fedora

If you're on a system with SELinux enabled and the above fixes don't work:

Check if SELinux is blocking:

bash
sudo ausearch -m avc -ts recent | grep docker

Temporary workaround (not for production):

bash
sudo setenforce 0
docker run myimage

Proper fix - relabel Docker storage:

bash
sudo semanage fcontext -a -t container_file_t "/var/lib/docker(/.*)?"
sudo restorecon -R /var/lib/docker

Or use the :Z flag when mounting volumes:

bash
docker run -v /host/path:/container/path:Z myimage

Advanced notes

### Alpine Linux Considerations

Alpine uses /bin/sh (busybox ash), not bash. If your shebang is #!/bin/bash, it will fail with "permission denied" or "not found". Use:

dockerfile
FROM alpine:3.18
RUN apk add --no-cache bash
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]

Or write POSIX-compatible scripts that work with /bin/sh.

### Multi-stage Build Permissions

When copying files between stages, permissions are preserved:

dockerfile
FROM node:18 AS builder
COPY entrypoint.sh /app/
RUN chmod +x /app/entrypoint.sh

FROM node:18-alpine
COPY --from=builder /app/entrypoint.sh /entrypoint.sh
# Permission is preserved from builder stage
ENTRYPOINT ["/entrypoint.sh"]

### CI/CD Pipeline Best Practices

In CI/CD, ensure consistent line endings:

yaml
# .gitlab-ci.yml example
before_script:
  - apt-get update && apt-get install -y dos2unix
  - find . -name "*.sh" -exec dos2unix {} \;
  - find . -name "*.sh" -exec chmod +x {} \;

### Debugging Permission Issues

To inspect a failing container's filesystem:

bash
# Create container without starting it
docker create --name debug myimage

# Copy the entrypoint out
docker cp debug:/entrypoint.sh ./debug-entrypoint.sh

# Check permissions and content
ls -la ./debug-entrypoint.sh
file ./debug-entrypoint.sh
head -1 ./debug-entrypoint.sh | cat -A

# Clean up
docker rm debug

### The noexec Mount Issue

If your Docker storage (/var/lib/docker) is on a filesystem mounted with noexec, all containers will fail with this error:

bash
# Check mount options
mount | grep "$(df /var/lib/docker | tail -1 | awk '{print $1}')"

# Remount with exec (temporary)
sudo mount -o remount,exec /var/lib/docker

Edit /etc/fstab for a permanent fix.

Frequently asked questions

What does "exec user process caused: permission denied" mean?
When a Docker container starts, it attempts to execute the command or script specified in the ENTRYPOINT or CMD instruction. The "exec user process caused: permission denied" error occurs when the Linux kernel cannot execute that file. This happens at the execve() system call level, before your script even starts running.
How do I fix "exec user process caused: permission denied"?
This error occurs when Docker cannot execute the entrypoint script or binary, typically because the file lacks execute permissions, has Windows line endings (CRLF), or SELinux is blocking execution. The fix usually involves adding chmod +x or converting line endings.
What causes "exec user process caused: permission denied"?
Entrypoint script lacks execute permission (+x) in the Docker image Script has Windows line endings (CRLF) that corrupt the shebang line Missing or invalid shebang line at the start of the script
Is the "exec user process caused: permission denied" error serious?
It is a medium-severity error โ€” more of a blocker than a risk. The steps above resolve it.

Official resources & further reading