[BUG] bwrap: execvp /bin/bash: No such file or directory — sandbox completely broken on all merged-usr Linux distros (Debian/Ubuntu/Arch), still unfixed after 3+ prior reports (#41863, #69583, #88059, #64799)
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?
Claude Code version: 2.1.289
Environment:
- OS: Debian GNU/Linux 13 (trixie), merged-usr (
/bin,/lib,/lib64,/sbinare symlinks tousr/*) - Platform: WSL2, kernel
6.18.33.2-microsoft-standard-WSL2 - bubblewrap: 0.12.0
Summary
Every single Bash tool call fails immediately when the sandbox is enabled, with:
bwrap: execvp /bin/bash: No such file or directory
This happens for any command, including trivial ones (echo hello). The sandbox is non-functional, not merely over-restrictive, on any merged-usr distribution. Merged-usr (where /bin, /lib, /lib64, /sbin are symlinks into /usr) has been the default layout on Debian, Ubuntu, and Arch for years, so this likely affects a large share of Linux/WSL2 users, not an edge case.
What Should Happen?
The sandboxed Bash tool executes normally, as it does on non-merged-usr systems, and as confirmed it does when bwrap is invoked manually with the correct symlinks (see #69583's proof-of-concept).
Error Messages/Logs
● Bash(which bwrap && bwrap --version)
⎿ Error: Exit code 1
bwrap: execvp /bin/bash: No such file or directory
● Bash(echo hello)
⎿ Error: Exit code 1
bwrap: execvp /bin/bash: No such file or directory
Steps to Reproduce
- On any merged-usr Linux distro (Debian 12+/trixie, Ubuntu 23.04+, Arch) or WSL2 with such a distro, install Claude Code 2.1.289 with the default sandbox enabled.
- Run any Bash tool call, e.g.
echo hello. - Observe immediate failure:
bwrap: execvp /bin/bash: No such file or directory.
Claude Model
Sonnet (default)
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
2.1.289
Platform
Anthropic API
Operating System
Ubuntu/Debian Linux
Terminal/Shell
IntelliJ IDEA terminal
Additional Information
This exact bug has already been reported and root-caused multiple times (and then the tickets have been auto-closed):
- #41863 — same error, Ubuntu 24.04, Claude Code 2.1.89. Reporter proved manually that
bwrap --ro-bind /bin /bin --ro-bind /usr /usr --ro-bind /lib /lib --ro-bind /lib64 /lib64 --proc /proc --dev /dev /bin/bash -c "echo works"succeeds outside Claude Code. Closed "not planned" with no comment. - #69583 — same error, WSL2/Ubuntu, explicitly diagnosed: bwrap binds
/usrinto the new namespace but does not recreate the/bin -> usr/bin,/lib -> usr/lib,/lib64 -> usr/lib64compatibility symlinks, so the ELF interpreter path (/lib64/ld-linux-x86-64.so.2) can't resolve inside the sandbox andexecvpreturnsENOENT. Included a working proof-of-concept fix (bwrap --symlink usr/bin /bin --symlink usr/lib /lib --symlink usr/lib64 /lib64 ...). Closed as duplicate, but no fix shipped — the bug still reproduces in 2.1.289. - #88059 — Debian trixie, Claude Code 2.1.232+, same underlying cause (symlink-hardening guards added in 2.1.232 mishandle merged-usr symlinks) but surfaces as a mount failure instead:
Can't mount tmpfs on /newroot/bin: No such file or directory. Closed "not planned". - #64799 — Arch Linux, merged-usr, open. Different symptom (
Can't mount tmpfs on /newroot/lib64, fails at mount setup rather than at exec), but confirmsenableWeakerNestedSandbox: truedoes not work around this class of bug.
Root cause (per #69583, still applicable in 2.1.289)
The sandbox setup binds /usr (and other allow-listed paths) into the new mount namespace but does not recreate the /bin, /lib, /lib64, /sbin → usr/* compatibility symlinks that merged-usr systems rely on. Binaries' ELF interpreters are requested at absolute paths like /lib64/ld-linux-x86-64.so.2, which don't resolve inside the sandboxed root, so execvp fails with ENOENT.
Suggested fix
Detect merged-usr at sandbox-setup time (host /bin, /lib, /lib64, /sbin are symlinks resolving under /usr) and either:
- add
--symlink usr/bin /bin,--symlink usr/lib /lib,--symlink usr/lib64 /lib64,--symlink usr/sbin /sbinto the bwrap invocation when/usris in the allowed tree, or - as suggested in #88059, resolve such symlinks to their real target before building the allow/deny mount list, rather than dropping the symlink and masking a path that doesn't exist in the new root.
Impact / why this needs more than "not planned"
With the sandbox broken, the only workarounds are (a) sandbox.enabled: false, which removes the security boundary entirely, or (b) approving dangerouslyDisableSandbox: true on every single command, which defeats the purpose of per-command sandboxing and trains users to click through a bypass prompt reflexively. Given three prior closures without a shipped fix, and that merged-usr is the default on the most common Linux distros, I'd ask that this be reopened/tracked rather than closed as a duplicate without resolution again.
This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗