This error occurs when Docker cannot execute the entrypoint or command inside a container due to missing execute permissions on the target file, an invalid shebang, or SELinux/AppArmor blocking execution.
The OCI (Open Container Initiative) runtime error "exec: permission denied" indicates that Docker's container runtime (typically runc) attempted to execute a command inside the container but was denied permission. This happens at the very start of container creation, before your application code runs. The runtime tries to execute whatever is specified as the ENTRYPOINT or CMD in your Dockerfile (or overridden via `docker run`). If the target file lacks execute permissions, has an invalid shebang line, or is blocked by security modules like SELinux or AppArmor, the container fails to start with this error. This is a common issue when building images from scripts, using volume mounts that don't preserve permissions, or running containers on systems with mandatory access control (MAC) enabled. The error is distinct from permission issues accessing filesβit specifically means the executable itself cannot be run.
Check if your entrypoint script has the execute permission. In your Dockerfile, add:
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]If you're using a local file, ensure it has execute permissions before building:
chmod +x entrypoint.sh
docker build -t myimage .Verify inside a running container (if possible):
docker run --rm -it --entrypoint /bin/sh myimage -c "ls -la /entrypoint.sh"Ensure your script has a valid shebang as the very first line:
#!/bin/bash
# or
#!/bin/sh
# or for better portability
#!/usr/bin/env bashCommon shebang issues:
- Missing shebang entirely
- Space before the shebang: #!/bin/bash (invalid)
- Wrong interpreter path: #!/bin/bash when bash isn't installed (use #!/bin/sh for Alpine)
- BOM (byte order mark) at the start of the file from Windows editors
Check for hidden characters:
head -1 entrypoint.sh | cat -AThe output should show exactly #!/bin/bash$ (the $ represents end of line).
Windows-style line endings can cause the shebang to be interpreted as #!/bin/bash\r which fails. Convert to Unix line endings:
Using dos2unix:
dos2unix entrypoint.shUsing sed:
sed -i 's/\r$//' entrypoint.shIn your Dockerfile (fix during build):
COPY entrypoint.sh /entrypoint.sh
RUN sed -i 's/\r$//' /entrypoint.sh && chmod +x /entrypoint.shConfigure Git to preserve line endings:
# In .gitattributes
*.sh text eol=lfIf you're on a system with SELinux enabled, mounted volumes may be blocked from execution. Check SELinux status:
getenforceOption A: Add the :z or :Z flag to volume mounts:
docker run -v /host/path:/container/path:z myimage- :z - Relabels the content to be shared among containers
- :Z - Relabels the content as private (only this container)
Option B: Check for SELinux denials:
sudo ausearch -m avc -ts recent | grep dockerOption C: Temporarily set SELinux to permissive (for testing only):
sudo setenforce 0If this fixes the issue, create a proper SELinux policy rather than leaving it permissive.
AppArmor can block container operations. Check if AppArmor is causing the issue:
Check AppArmor status:
sudo aa-statusRun container with AppArmor disabled (for testing):
docker run --security-opt apparmor=unconfined myimageCheck AppArmor denials:
sudo dmesg | grep -i apparmor | tail -20If disabling AppArmor fixes the issue, consider creating a custom AppArmor profile rather than running unconfined in production.
If you're mounting a volume over a directory containing your entrypoint, the mounted content may override the executable:
Problematic setup:
# docker-compose.yml
volumes:
- ./src:/app # If /app/entrypoint.sh is your ENTRYPOINT, this overrides itSolutions:
1. Mount to a subdirectory instead:
volumes:
- ./src:/app/src2. Keep entrypoint outside the mounted path:
COPY entrypoint.sh /usr/local/bin/entrypoint.sh
RUN chmod +x /usr/local/bin/entrypoint.sh
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]3. Ensure the local file has execute permissions when mounting:
chmod +x ./src/entrypoint.shThe error can also occur if the specified command doesn't exist. Test interactively:
# Override entrypoint to get a shell
docker run --rm -it --entrypoint /bin/sh myimage
# Inside container, check if the binary exists
which my-binary
ls -la /path/to/entrypointFor Alpine-based images, remember that bash may not be installed:
# Use sh instead of bash
ENTRYPOINT ["/bin/sh", "/entrypoint.sh"]
# Or install bash
RUN apk add --no-cache bash### Understanding OCI Runtime Errors
The OCI (Open Container Initiative) runtime is the low-level component that actually creates and runs containers. Docker uses runc as its default OCI runtime. When you see "OCI runtime create failed," the error occurred at this layer, before your container code ran.
### Debugging with Verbose Output
Get more details about the failure:
docker run --rm myimage 2>&1 | cat -AOr check Docker daemon logs:
sudo journalctl -u docker.service -n 50### Rootless Docker Considerations
In rootless Docker mode, additional permission restrictions apply:
# Check if running rootless
docker info | grep -i rootlessRootless mode may have issues with:
- Privileged operations
- Certain volume mounts
- Network configurations
See the Docker rootless documentation for specific limitations.
### Multi-stage Build Gotcha
When using multi-stage builds, ensure you copy executables with the right permissions:
# Bad - may lose execute permission
COPY --from=builder /app/binary /app/binary
# Good - preserve permissions
COPY --from=builder --chmod=755 /app/binary /app/binary### Container Runtime Alternatives
If runc continues to have issues, you can try alternative runtimes:
# Use crun (faster, written in C)
docker run --runtime=crun myimage
# Check available runtimes
docker info | grep -i runtime### Exec Format Error vs Permission Denied
Don't confuse this error with "exec format error" which means:
- Wrong architecture (ARM image on x86 or vice versa)
- Binary compiled for wrong OS
- Corrupted executable
Permission denied specifically means the file exists but cannot be executed.
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