What is the fastest way to confirm it is AppArmor?
Run sysctl kernel.apparmor_restrict_unprivileged_userns: only a return of 1 needs the AppArmor profile; 0 or a missing key means skip. That is the official docs' check; I have not run it.
Does adding that AppArmor profile give commands inside the Sandbox more power?
Per the official docs, no: the profile applies only to bwrap itself, not to the commands it runs inside the sandbox. It does grant bwrap on the system the user-namespace capability, so judge it against your environment's policy.
The Sandbox will not start yet Claude still runs commands. Is that normal?
The docs say that is the default: with a missing dependency or an unsupported platform, Claude Code runs commands without sandboxing. To make it exit instead, set sandbox.failIfUnavailable: true.
I'm not an engineer. One-line version?
The Sandbox is a partitioned room, and Ubuntu's security policy by default does not let anyone build the partition; you first permit the tool that builds it, and only then can the room go up.
On Ubuntu 24.04 and later, you can install bubblewrap and socat and still find Claude Code's Sandbox will not start; a common cause is that AppArmor's default policy stops bubblewrap from creating the user namespaces it needs. The official sandbox docs have a dedicated section for it, and v2.1.310 made /sandbox and the startup warning name this restriction directly. This article follows the official docs for checking and fixing it; I did not run the commands on an Ubuntu machine, so please confirm in your own environment.
The docs' check (it applies inside WSL2 too):
sysctl kernel.apparmor_restrict_unprivileged_userns
0: skip this step.No such file or directory: the key does not exist, skip this step too.1: add an AppArmor profile that grants bwrap this capability.Separately, the Dependencies tab in /sandbox lists which of ripgrep, bubblewrap, socat and the seccomp filter are missing; the dependency check runs at startup, so restart Claude Code after installing packages. If you do not see the tab, all dependencies are present.
sudo tee /etc/apparmor.d/bwrap > /dev/null <<'EOF'
abi <abi/4.0>,
include <tunables/global>
profile bwrap /usr/bin/bwrap flags=(unconfined) {
userns,
include if exists <local/bwrap>
}
EOF
sudo systemctl reload apparmor
The docs stress that this profile applies only to bwrap itself, not to the commands it runs inside the sandbox. It authorizes the act of creating the sandbox, not looser rules for programs inside it. That is a different layer from the sandbox.allowNestedUserNamespaces setting covered earlier: that one lets commands inside the sandbox create user namespaces, and the docs warn it turns off a security boundary; the AppArmor step only lets the sandbox start.
The docs say that by default, if the sandbox cannot start because a dependency is missing or the platform is unsupported, Claude Code runs commands without sandboxing; set sandbox.failIfUnavailable to true to make it exit at startup instead. The docs name the missing-dependency and unsupported-platform cases; whether an AppArmor Block counts is not stated, and treating it as such is my inference. If you rely on the sandbox, I suggest doing both: fix AppArmor, and consider failIfUnavailable, with allowUnsandboxedCommands: false in administrator deployments. The docs also warn that the sandbox does not run on native Windows, so with failIfUnavailable set Claude Code exits at startup on those machines.
One of the docs' probes: touch ~/sandbox-probe should fail with Read-only file system on Linux and WSL2 (Operation not permitted on macOS); curl --noproxy '*' https://example.com should fail with Could not resolve host, because the command has no route around the sandbox proxy. The docs also say to decline any Claude offer to retry a failed command outside the sandbox; if touch succeeds and your home directory is not one the sandbox lets commands write to, delete ~/sandbox-probe and run /sandbox to check.
/proc, so sandboxed commands fail with a bwrap error such as Can't mount proc on /newroot/proc: Operation not permitted. The docs' fix is enableWeakerNestedSandbox: true, with a warning to use it only when the outer container already provides the isolation you need, since it exposes process information that a fresh /proc mount would hide.Sandboxing requires WSL2, your distribution runs on WSL1; upgrade to WSL2 or run Claude Code without the sandbox. Check with wsl -l -v.This is my summary, not official advice: when the sandbox will not start, follow what /sandbox tells you first; on Ubuntu 24.04 and later check that sysctl; containers and WSL1 are separate paths, so do not mix their fixes. Above all, do not turn on allowNestedUserNamespaces just to make the sandbox look healthy; it solves a different problem.