How to fix OCI runtime create failed: container_linux.go: starting container process caused: exec: permission denied in Docker

DockerINTERMEDIATEMEDIUMUpdated Dec 6, 2025Β· 390 views

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.

Quick fix

Fixes OCI runtime create failed: container_linux.go: starting container process caused: exec: permission denied

COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
  1. Verify the entrypoint file has execute permissions
  2. Check the shebang line in your script
  3. Fix Windows line endings (CRLF to LF)
  4. Handle SELinux on CentOS/RHEL/Fedora
docker β€” error
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
OCI runtime create failed: container_linux.go: starting container process caused: exec: permission denied

What this error means

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.

Typical symptoms

  • Container fails to start immediately after docker run or docker-compose up
  • Error message includes 'OCI runtime create failed' and 'permission denied'
  • Container exits instantly without producing any logs
  • Same image works on one machine but fails on another (often SELinux-related)
  • Container worked before but fails after mounting a volume over the entrypoint location
  • CI/CD pipelines fail at container start with no application output

Common causes

  1. Entrypoint or CMD script lacks execute permission (chmod +x not applied)
  2. Invalid or missing shebang line (#!/bin/bash) in the script
  3. SELinux is blocking execution of mounted files (common on CentOS/RHEL/Fedora)
  4. AppArmor profile is restricting container operations (common on Ubuntu)
  5. Volume mount is overriding an executable file with a non-executable version
  6. Windows line endings (CRLF) in shell scripts causing interpreter issues
  7. The specified binary does not exist at the expected path
  8. File system mounted as noexec preventing script execution

How to fix "OCI runtime create failed: container_linux.go: starting container process caused: exec: permission denied"

1Verify the entrypoint file has execute permissions

Check if your entrypoint script has the execute permission. In your Dockerfile, add:

dockerfile
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:

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

Verify inside a running container (if possible):

bash
docker run --rm -it --entrypoint /bin/sh myimage -c "ls -la /entrypoint.sh"
2Check the shebang line in your script

Ensure your script has a valid shebang as the very first line:

bash
#!/bin/bash
# or
#!/bin/sh
# or for better portability
#!/usr/bin/env bash

Common 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:

bash
head -1 entrypoint.sh | cat -A

The output should show exactly #!/bin/bash$ (the $ represents end of line).

3Fix Windows line endings (CRLF to LF)

Windows-style line endings can cause the shebang to be interpreted as #!/bin/bash\r which fails. Convert to Unix line endings:

Using dos2unix:

bash
dos2unix entrypoint.sh

Using sed:

bash
sed -i 's/\r$//' entrypoint.sh

In your Dockerfile (fix during build):

dockerfile
COPY entrypoint.sh /entrypoint.sh
RUN sed -i 's/\r$//' /entrypoint.sh && chmod +x /entrypoint.sh

Configure Git to preserve line endings:

bash
# In .gitattributes
*.sh text eol=lf
4Handle SELinux on CentOS/RHEL/Fedora

If you're on a system with SELinux enabled, mounted volumes may be blocked from execution. Check SELinux status:

bash
getenforce

Option A: Add the :z or :Z flag to volume mounts:

bash
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:

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

Option C: Temporarily set SELinux to permissive (for testing only):

bash
sudo setenforce 0

If this fixes the issue, create a proper SELinux policy rather than leaving it permissive.

5Handle AppArmor on Ubuntu/Debian

AppArmor can block container operations. Check if AppArmor is causing the issue:

Check AppArmor status:

bash
sudo aa-status

Run container with AppArmor disabled (for testing):

bash
docker run --security-opt apparmor=unconfined myimage

Check AppArmor denials:

bash
sudo dmesg | grep -i apparmor | tail -20

If disabling AppArmor fixes the issue, consider creating a custom AppArmor profile rather than running unconfined in production.

6Check for volume mount conflicts

If you're mounting a volume over a directory containing your entrypoint, the mounted content may override the executable:

Problematic setup:

yaml
# docker-compose.yml
volumes:
  - ./src:/app  # If /app/entrypoint.sh is your ENTRYPOINT, this overrides it

Solutions:

1. Mount to a subdirectory instead:

yaml
volumes:
  - ./src:/app/src

2. Keep entrypoint outside the mounted path:

dockerfile
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:

bash
chmod +x ./src/entrypoint.sh
7Verify the binary exists in the container

The error can also occur if the specified command doesn't exist. Test interactively:

bash
# 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/entrypoint

For Alpine-based images, remember that bash may not be installed:

dockerfile
# Use sh instead of bash
ENTRYPOINT ["/bin/sh", "/entrypoint.sh"]

# Or install bash
RUN apk add --no-cache bash

Advanced notes

### 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:

bash
docker run --rm myimage 2>&1 | cat -A

Or check Docker daemon logs:

bash
sudo journalctl -u docker.service -n 50

### Rootless Docker Considerations

In rootless Docker mode, additional permission restrictions apply:

bash
# Check if running rootless
docker info | grep -i rootless

Rootless 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:

dockerfile
# 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:

bash
# 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.

Frequently asked questions

What does "OCI runtime create failed: container_linux.go: starting container proc" mean?
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).
How do I fix "OCI runtime create failed: container_linux.go: starting container proc"?
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.
What causes "OCI runtime create failed: container_linux.go: starting container proc"?
Entrypoint or CMD script lacks execute permission (chmod +x not applied) Invalid or missing shebang line (#!/bin/bash) in the script SELinux is blocking execution of mounted files (common on CentOS/RHEL/Fedora)
Is the "OCI runtime create failed: container_linux.go: starting container proc" error serious?
It is a medium-severity error β€” more of a blocker than a risk. The steps above resolve it.

Official resources & further reading