Bash sandbox intermittently fails with apply-seccomp: unshare(CLONE_NEWUSER): Invalid argument

Status Closed — duplicate
Reported on v2.1.233
Maintainer reply None cached
Activity 2 comments · opened Aug 16, 2026 · closed Aug 20, 2026

What happens

Roughly one Bash call in three fails with

apply-seccomp: unshare(CLONE_NEWUSER): Invalid argument

printed instead of the command's output. The command does not run. Re-running
the identical command usually succeeds within one to three attempts. The rate
rises as a session ages.

Because the message replaces stdout rather than accompanying it, every failure
initially reads as the command itself failing — a git push that printed
nothing, a stat that found nothing.

Root cause

unshare(CLONE_NEWUSER) implies CLONE_THREAD, which the kernel refuses with
EINVAL when the calling process has more than one thread. The sandbox helper
sometimes invokes it from a multithreaded context, which is why the failure is
intermittent rather than constant.

Reduced to a standalone reproducer — forks a child per case so the parent's
thread state is untouched, then calls libc.unshare(CLONE_NEWUSER):

single-threaded: OK
multithreaded  : FAIL EINVAL (Invalid argument)

Measured in one session: 5 failures in 19 Bash calls.

This is not #43454

https://github.com/anthropics/claude-code/issues/43454 is
write /proc/self/setgroups … Permission deniedEPERM, a nested-userns
capability problem. This is EINVAL from a multithreaded caller. Same helper,
different failure, different fix.

Ruled out

  • AppArmor. kernel.apparmor_restrict_unprivileged_userns=1 is set, but

/etc/apparmor.d/unprivileged_userns grants allow userns, unshare --user
succeeds from a shell, and journalctl -k --since '-14d' shows zero
userns_create denials.

  • Missing packages. Sandboxing works; it just fails intermittently.
  • Nesting. Not running in a container.

Environment

  • Claude Code 2.1.233
  • Linux 7.0.0-28-generic #28~24.04.1-Ubuntu SMP PREEMPT_DYNAMIC x86_64
  • Ubuntu 24.04, bare metal, no container
  • sandbox.enabled: true, autoAllowBashIfSandboxed: true

Suggested fix

Perform the unshare before spawning helper threads, or do it in a
single-threaded forked child. Failing that, retry internally on EINVAL rather
than surfacing it, and never print the helper's error in place of the command's
own output — that conflation is most of the operational cost.

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗