This error occurs when Docker cannot start a container using gVisor's runsc runtime. Common causes include incorrect installation, misconfigured Docker daemon, kernel incompatibilities, or SELinux restrictions.
The "OCI runtime create failed: runsc error" message indicates that Docker attempted to start a container using gVisor's runsc runtime but encountered a failure during container creation. gVisor is a user-space kernel that provides an additional layer of isolation between containers and the host system by intercepting and handling system calls. When you configure Docker to use runsc as the runtime (instead of the default runc), Docker delegates container creation to gVisor. If runsc fails to initialize the sandbox, create the container filesystem, or set up the necessary isolation primitives, this error is thrown. The error is often accompanied by more specific details in Docker's error output or in runsc's debug logs, such as "operation not permitted," "invalid argument," or "cannot create sandbox." These details are crucial for diagnosing the root cause.
First, confirm that runsc is properly installed and accessible:
which runsc
runsc --versionIf runsc is not found, install it following the official gVisor installation guide:
# Add the gVisor repository key
curl -fsSL https://gvisor.dev/archive.key | sudo gpg --dearmor -o /usr/share/keyrings/gvisor-archive-keyring.gpg
# Add the repository
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/gvisor-archive-keyring.gpg] https://storage.googleapis.com/gvisor/releases release main" | sudo tee /etc/apt/sources.list.d/gvisor.list > /dev/null
# Install runsc
sudo apt-get update && sudo apt-get install -y runscEnsure runsc is in a location readable and executable by all users (important for unprivileged operation):
ls -la $(which runsc)
# Should show: -rwxr-xr-x ... /usr/bin/runscAdd gVisor as a runtime option in Docker's daemon configuration. Edit /etc/docker/daemon.json:
{
"runtimes": {
"runsc": {
"path": "/usr/bin/runsc"
}
}
}For more control, you can add runtime arguments:
{
"runtimes": {
"runsc": {
"path": "/usr/bin/runsc",
"runtimeArgs": [
"--platform=systrap",
"--network=sandbox"
]
},
"runsc-debug": {
"path": "/usr/bin/runsc",
"runtimeArgs": [
"--debug-log=/tmp/runsc/",
"--debug",
"--strace"
]
}
}
}Restart Docker to apply changes:
sudo systemctl restart dockerVerify the runtime is registered:
docker info | grep -A5 "Runtimes"gVisor requires specific kernel features and has known issues with certain kernel versions. Check your kernel version:
uname -rKnown problematic kernel versions:
- Linux 5.1 to 5.3.15
- Linux 5.4.2
- Linux 5.5
If you're running one of these versions, upgrade your kernel:
# Ubuntu/Debian
sudo apt-get update
sudo apt-get upgrade linux-generic
# Check for available kernels
apt list --installed | grep linux-imageMinimum kernel requirements:
- Kernel 4.14.77+ recommended
- Kernel must support user namespaces
Verify user namespace support:
cat /proc/sys/kernel/unprivileged_userns_clone
# Should return 1If disabled, enable it:
sudo sysctl -w kernel.unprivileged_userns_clone=1
echo "kernel.unprivileged_userns_clone=1" | sudo tee /etc/sysctl.d/99-userns.confIf SELinux is enabled, it may block gVisor operations. Check SELinux status:
getenforcegVisor doesn't support setting SELinux labels. For containers using runsc, disable SELinux for specific containers:
docker run --runtime=runsc --security-opt label=disable <image>Or run in permissive mode temporarily for testing:
sudo setenforce 0Note: Disabling SELinux reduces security. In production, consider using gVisor's built-in isolation instead of relying on SELinux for container isolation.
For Docker Compose:
services:
myapp:
runtime: runsc
security_opt:
- label:disableIf the error persists, enable gVisor debug logging to get detailed information:
Configure a debug runtime in /etc/docker/daemon.json:
{
"runtimes": {
"runsc-debug": {
"path": "/usr/bin/runsc",
"runtimeArgs": [
"--debug-log=/tmp/runsc/",
"--debug",
"--strace"
]
}
}
}Important: The trailing / in --debug-log=/tmp/runsc/ is required to interpret it as a directory.
Create the log directory and set permissions:
sudo mkdir -p /tmp/runsc
sudo chmod 777 /tmp/runscRestart Docker and run with the debug runtime:
sudo systemctl restart docker
docker run --runtime=runsc-debug hello-worldCheck the logs:
ls -la /tmp/runsc/
# Look for files ending in .create for container creation issues
# Files ending in .boot contain application syscall traces
cat /tmp/runsc/runsc.log.*.createThe "operation not permitted" error often indicates permission or namespace issues.
Check if Docker is running in rootless mode:
docker info | grep "rootless"gVisor has limited support for rootless Docker. If running rootless, try with root Docker instead.
Verify /proc/self/exe accessibility:
The error "fork/exec /proc/self/exe: operation not permitted" suggests issues with executing runsc. Ensure:
# runsc can re-execute itself
ls -la /proc/self/exeCheck cgroup configuration:
# Verify cgroup v2 (unified hierarchy)
mount | grep cgroup
cat /sys/fs/cgroup/cgroup.controllersFor cgroup v2 systems, ensure Docker is configured properly:
{
"exec-opts": ["native.cgroupdriver=systemd"],
"runtimes": {
"runsc": {
"path": "/usr/bin/runsc"
}
}
}Before debugging complex containers, verify runsc works with a minimal test:
# Test basic functionality
docker run --runtime=runsc --rm hello-world
# Test with a simple shell
docker run --runtime=runsc --rm -it alpine:latest echo "gVisor working!"If these work but your application fails, the issue is likely application-specific:
Common application compatibility issues:
- Direct hardware access (not supported)
- Certain system calls not implemented in gVisor
- /dev/mem or other device files
- Specific kernel features your app requires
Check gVisor's compatibility documentation for your use case:
# Run with strace to see which syscalls are failing
docker run --runtime=runsc-debug --rm your-image
cat /tmp/runsc/runsc.log.*.boot | grep -i "not implemented"Understanding gVisor Architecture: gVisor (runsc) implements a user-space kernel called Sentry that intercepts system calls from the containerized application. This provides stronger isolation than traditional containers but with some compatibility and performance trade-offs. Not all system calls are implemented, which can cause some applications to fail.
Platform Selection: gVisor supports multiple platforms for system call interception:
- systrap: Uses SIGSYS signal (default, recommended)
- kvm: Uses KVM for hardware virtualization (better performance, requires KVM)
Configure in daemon.json:
{
"runtimes": {
"runsc-kvm": {
"path": "/usr/bin/runsc",
"runtimeArgs": ["--platform=kvm"]
}
}
}Network Modes: gVisor's default sandbox network isolates containers from the host network stack. The embedded DNS server binds to 127.0.0.10 on the loopback interface. For Docker user-defined bridge networks, you may see DNS resolution issues because the sandbox cannot access the host's DNS server without breaking isolation.
Containerd Integration: For Kubernetes or containerd-based setups, configure containerd's config.toml:
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runsc]
runtime_type = "io.containerd.runsc.v1"GPU Support: gVisor has experimental GPU support through nvproxy. For GPU workloads:
docker run --runtime=runsc --gpus all nvidia/cuda:latest nvidia-smiNote: Rootless mode with GPU is not supported and will fail with "operation not permitted."
Debugging Sandbox Failures: For "cannot create sandbox" errors, check:
1. User namespace support in kernel
2. Mount namespace permissions
3. Seccomp and AppArmor profiles
4. Available file descriptors (ulimit -n)
# Check system limits
ulimit -a
cat /proc/sys/fs/file-maxPerformance Tuning: gVisor adds overhead due to syscall interception. For performance-critical workloads:
- Use --platform=kvm if available
- Reduce syscall-heavy operations
- Consider using runc for performance-critical containers and runsc for untrusted workloads
unable to configure the Docker daemon with file /etc/docker/daemon.json
How to fix 'unable to configure the Docker daemon with file daemon.json' in Docker
docker: Error response from daemon: OCI runtime create failed: container_linux.go: starting container process caused: exec: "/docker-entrypoint.sh": stat /docker-entrypoint.sh: no such file or directory
How to fix 'exec: entrypoint.sh: no such file or directory' in Docker
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
dockerfile parse error line 5: unknown instruction: RRUN
How to fix 'unknown instruction' Dockerfile parse error in Docker
manifest unknown: manifest unknown
How to fix 'manifest unknown' in Docker