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.
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.
The most common fix is to explicitly set execute permissions in your Dockerfile after copying the script:
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]If you're copying multiple scripts:
COPY scripts/ /scripts/
RUN chmod +x /scripts/*.shImportant: Always use the exec form (JSON array) for ENTRYPOINT, not the shell form.
If you edited the script on Windows, convert line endings in your 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:
RUN apt-get update && apt-get install -y dos2unix
COPY entrypoint.sh /entrypoint.sh
RUN dos2unix /entrypoint.sh && chmod +x /entrypoint.shBetter long-term fix: Configure Git to preserve LF endings for shell scripts by adding a .gitattributes file:
*.sh text eol=lfEnsure your script starts with a valid shebang on the very first line:
#!/bin/bash
# or for Alpine/minimal images:
#!/bin/sh
# or for maximum portability:
#!/usr/bin/env shCommon 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:
head -1 entrypoint.sh | cat -AYou should see exactly #!/bin/bash$ (or similar). Any ^M indicates CRLF line endings.
Docker's COPY instruction preserves file permissions from your build context. Fix permissions on your host machine:
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:
ls -la entrypoint.sh
# Should show: -rwxr-xr-x (the x's indicate execute permission)If you can't modify the Dockerfile or need a quick workaround, explicitly invoke the shell:
ENTRYPOINT ["sh", "/entrypoint.sh"]
# or
ENTRYPOINT ["/bin/sh", "-c", "/entrypoint.sh"]Or override at runtime:
docker run myimage sh /entrypoint.shThis 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.
If you're on a system with SELinux enabled and the above fixes don't work:
Check if SELinux is blocking:
sudo ausearch -m avc -ts recent | grep dockerTemporary workaround (not for production):
sudo setenforce 0
docker run myimageProper fix - relabel Docker storage:
sudo semanage fcontext -a -t container_file_t "/var/lib/docker(/.*)?"
sudo restorecon -R /var/lib/dockerOr use the :Z flag when mounting volumes:
docker run -v /host/path:/container/path:Z myimage### 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:
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:
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:
# .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:
# 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:
# 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/dockerEdit /etc/fstab for a permanent fix.
image operating system "linux" cannot be used on this platform
How to fix 'image operating system linux cannot be used on this platform' in Docker
manifest unknown: manifest unknown
How to fix 'manifest unknown' in Docker
cannot open '/etc/passwd': Permission denied
How to fix 'cannot open: Permission denied' in Docker
Error response from daemon: failed to create the ipvlan port
How to fix 'failed to create the ipvlan port' in Docker
toomanyrequests: Rate exceeded for anonymous users
How to fix 'Rate exceeded for anonymous users' in Docker Hub