[BUG] Sandbox fails inside Docker containers: nested user namespace in apply-seccomp causes EACCES on /proc/self/setgroups
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
When running Claude Code inside a Docker container as a non-root user with sandbox enabled, all bash commands fail with:
apply-seccomp: write /proc/self/setgroups (nested userns is capability-restricted; caller must provide CAP_SYS_ADMIN): Permission denied
The root cause is a nested user namespace. The sandbox call chain is:
- Claude Code invokes
bwrap --unshare-net ... - Because the container user is non-root, bwrap must call
unshare(CLONE_NEWUSER)to obtainCAP_NET_ADMINfor--unshare-net→ userns layer 1 - bwrap then
execvesapply-seccomp, which callsunshare(CLONE_NEWUSER)again → userns layer 2 (nested) - Inside the nested userns,
apply-seccomptries toopen("/proc/self/setgroups", O_WRONLY)→ EACCES
The kernel denies writes to /proc/self/setgroups in a nested user namespace. This is a hard kernel restriction, not configurable via sysctl or AppArmor.
Confirmed via strace:
# bwrap creates first userns
1218 unshare(CLONE_NEWUSER) = 0
# apply-seccomp creates second (nested) userns
1222 unshare(CLONE_NEWNS|CLONE_NEWPID) = -1 EPERM (Operation not permitted)
1222 unshare(CLONE_NEWUSER) = 0
1222 openat(AT_FDCWD, "/proc/self/setgroups", O_WRONLY) = -1 EACCES (Permission denied)
None of the following help:
kernel.apparmor_restrict_unprivileged_userns=0on hostseccomp=unconfined,apparmor=unconfined,cap_add: SYS_ADMINin Docker Composechmod u+s /usr/bin/bwrap(bwrap 0.11.0 still enters userns)setcap cap_net_admin,cap_sys_admin+eip /usr/bin/bwrap
Running as root inside the container works (bwrap skips userns), but is undesirable for security.
What Should Happen?
Claude Code sandbox should work inside Docker containers when running as a non-root user, or gracefully degrade (e.g., skip the apply-seccomp layer when nested userns is detected) instead of failing all bash commands.
Error Messages/Logs
apply-seccomp: write /proc/self/setgroups (nested userns is capability-restricted; caller must provide CAP_SYS_ADMIN): Permission denied
Steps to Reproduce
- Create a Docker Compose service running a Debian-based image with Claude Code installed
- Run the container as a non-root user (e.g., uid 996)
- Docker Compose config:
```yaml
cap_add:
- SYS_ADMIN
- SYS_PTRACE
- NET_ADMIN
security_opt:
- seccomp=unconfined
- apparmor=unconfined
```
- Enter the container and run Claude Code with sandbox enabled
- Execute any bash command (e.g.,
echo "hello") - Observe the
apply-seccomppermission denied error
Claude Model
Opus
Is this a regression?
Yes, this worked in a previous version
Last Working Version
2.1.91
Claude Code Version
2.1.108
Platform
Anthropic API
Operating System
Ubuntu/Debian Linux
Terminal/Shell
Non-interactive/CI environment
Additional Information
Host: Ubuntu 24.04, kernel 6.8.0-100-generic
Container base: Debian Trixie
bubblewrap: 0.11.0
Workaround: Replace apply-seccomp with a passthrough script. This preserves bwrap's namespace isolation (network, mount, pid, session) while skipping the nested userns:
printf '#!/bin/sh\nexec "$@"\n' > /usr/lib/node_modules/@anthropic-ai/claude-code/vendor/seccomp/x64/apply-seccomp && \
chmod +x /usr/lib/node_modules/@anthropic-ai/claude-code/vendor/seccomp/x64/apply-seccomp
Suggested fixes:
- Detect nested userns and skip
apply-seccompautomatically - Merge isolation layers — have bwrap handle seccomp directly via
--seccompinstead of delegating to a separate binary - Add a config option (e.g.,
CLAUDE_SANDBOX_SECCOMP=false) to disable theapply-seccomplayer independently - Skip
--unshare-netwhen network is already restricted, avoiding the userns requirement for non-root users
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗