[BUG] 2.1.216 sandbox regression: default `--cap-drop ALL` breaks all Bash on root installs (apply-seccomp: write /proc/self/uid_map: Operation not permitted)
Preflight Checklist
- [x] I have searched existing issues. The closest are #43454, #48304, #73786, #44180 — this is a distinct regression (root install,
uid_mapwrite, introduced by 2.1.216's new--cap-drop ALLdefault); see "Relation to existing issues" below. - [x] This is a single bug report.
- [x] I am using the latest version of Claude Code.
What's Wrong?
Starting with 2.1.216, on a Claude Code install that runs as root on Linux/WSL2 (kernel ≥ 5.12), every sandboxed Bash tool call dies before the user command runs:
apply-seccomp: write /proc/self/uid_map: Operation not permitted
2.1.215 worked fine. 2.1.216 auto-updated overnight and broke all Bash. dangerouslyDisableSandbox: true does not help (the sandboxed pre-flight dies first).
Root cause (from inspecting the bundled binaries): 2.1.216 added --unshare-user --cap-drop ALL to the default bwrap sandbox args (the non-weaker branch). In 2.1.215 that branch was just --dev /dev --unshare-pid --proc /proc — no user namespace, no capability drop.
Independently verifiable regression marker (no decompiler needed — the string is entirely new in 2.1.216):
$ for v in 2.1.212 2.1.215 2.1.216; do
printf '%s: ' "$v"
strings -a ~/.local/share/claude/versions/$v | grep -c -- '--cap-drop'
done
2.1.212: 0
2.1.215: 0
2.1.216: 2
Why it only breaks root installs: the sandbox re-execs the bundled apply-seccomp helper, which creates a nested user namespace and writes 0 0 1 to /proc/self/uid_map. Since Linux 5.12, the kernel's verify_root_map check requires CAP_SETFCAP to map uid 0. But the preceding --cap-drop ALL empties the bounding set, so the euid-0 process re-execed inside the userns holds zero capabilities (CapBnd/CapEff = 0000000000000000) → the uid-0 map write returns EPERM. A non-root install maps e.g. 1000 1000 1 (lower id ≠ 0), so verify_root_map never fires — which is exactly why this is root-specific, and why the closely-related #43454 / #48304 (non-root, failing at the earlier setgroups write) are a different manifestation of the same nested-userns fragility rather than the same bug.
What Should Happen?
Sandboxed Bash should run on root installs, as it did in 2.1.215.
Confirmed fix
Adding --cap-add CAP_SETFCAP to the bwrap invocation (retaining just that one capability through the drop) makes the uid-0 map succeed and Bash works again — verified by replaying 2.1.216's exact wrapper args with --cap-add CAP_SETFCAP added. Alternatively, skip the nested uid_map write (or use an identity map) when geteuid() == 0.
Error Messages/Logs
apply-seccomp: write /proc/self/uid_map: Operation not permitted
Steps to Reproduce
- Run Claude Code as root on Linux or WSL2 (kernel ≥ 5.12).
- Native Bash sandbox enabled (
sandbox.enabled: true). - On ≥ 2.1.216, every Bash tool call fails with the error above. On ≤ 2.1.215 it works. The only delta is the new
--unshare-user --cap-drop ALLdefault args (see thestringsmarker above).
Workarounds (for other root users hitting this)
sandbox.network.allowAllUnixSockets: truein settings — skips theapply-seccompseccomp step entirely while keeping the rest of the 2.1.216 sandbox (filesystem binds,--unshare-net,--cap-drop ALL). Confirmed working. (Related feature: #44180.)sandbox.enableWeakerNestedSandbox: trueavoids--cap-drop ALL, but is silently forced tofalsewhenCLAUDE_CODE_SUBPROCESS_ENV_SCRUBis set (#73786), so it is not a reliable workaround.- Pin/downgrade to 2.1.215 — but the auto-updater re-bumps to ≥ 2.1.216 on next launch.
Relation to existing issues
- #43454 / #48304 — same
apply-seccompnested-userns capability restriction, but those fail at the earlier/proc/self/setgroupswrite on non-root installs and predate the--cap-drop ALLdefault. This report is the root +uid_map+ 2.1.216--cap-drop ALLvariant. - #73786 — the
CLAUDE_CODE_SUBPROCESS_ENV_SCRUBinteraction that makesenableWeakerNestedSandboxa non-workaround here. - #44180 — the
allowAllUnixSocketsknob used as the working workaround.
Claude Model
Opus
Is this a regression?
Yes.
Last Working Version
2.1.215
Claude Code Version
2.1.216
Platform
Claude subscription (Max)
Operating System
WSL2 (Ubuntu) on Windows, kernel 6.6.114.1-microsoft-standard-WSL2, Claude Code running as root.
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗