[BUG] Cowork on Debian 12: helper resolves system C virtiofsd instead of bundled Rust virtiofsd, causing setgroups/FUSE failures
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?
<html><head></head><body><h3>What's Wrong?</h3>
<p>Cowork fails to start on Debian 12 (Bookworm) using the official <code>.deb</code> from <code>downloads.claude.ai</code>. The <code>cowork-linux-helper</code> spawns <code>virtiofsd</code> inside a user namespace where two syscall/permission issues prevent the socket from being created.</p>
<p><strong>Error 1: <code>setgroups()</code> denied in user namespace</strong></p>
<pre><code>[virtiofsd] setgroups() failed with error=1:Operation not permitted
</code></pre>
<p>The Go helper creates a user namespace and spawns virtiofsd inside it. The <code>setgroups()</code> syscall is denied because <code>/proc/self/setgroups</code> defaults to <code>deny</code> in unprivileged user namespaces. This causes virtiofsd to crash before creating the socket.</p>
<p>This was mitigated with a compiled C wrapper around <code>cowork-linux-helper</code> that installs a seccomp-bpf filter returning <code>ERRNO(0)</code> for <code>__NR_setgroups</code> before exec'ing the real helper.</p>
<p><strong>Error 2: FUSE <code>invalid argument</code> on socket path</strong></p>
<pre><code>[virtiofsd] fuse: invalid argument `/run/user/1000/cowork-vm-XXXXXXXXXX/virtiofsd-0.sock'
</code></pre>
<p>After mitigating the setgroups error, virtiofsd still fails with a FUSE error. The FUSE device setup inside the helper's user namespace fails, even on kernel 6.12 where user namespace FUSE support is improved. This appears to be the helper's namespace configuration not properly exposing <code>/dev/fuse</code> or not setting up the namespace with the right FUSE permissions.</p>
<p><strong>The bundled virtiofsd works fine standalone:</strong></p>
<pre><code class="language-bash">/usr/lib/claude-desktop/resources/virtiofsd \
--socket-path=/tmp/test.sock \
--shared-dir=/tmp \
--sandbox=none
Output: [INFO virtiofsd] Waiting for vhost-user socket connection...
</code></pre>
<p>This confirms the binary is functional -- the issue is entirely within the user namespace that <code>cowork-linux-helper</code> creates.</p>
<h3>Environment</h3>
<ul>
<li><strong>Package:</strong> Official <code>.deb</code> from <code>downloads.claude.ai/claude-desktop/apt/stable</code>, version <code>1.22209.0</code></li>
<li><strong>OS:</strong> Debian 12 (Bookworm), amd64</li>
<li><strong>Kernels tested:</strong> 6.1.0-50-amd64 (stock Bookworm) and 6.12.95+deb12-amd64 (bookworm-backports) -- same failure on both</li>
<li><strong>GPU:</strong> NVIDIA (proprietary driver 535.261.03, DKMS)</li>
<li><strong>Display:</strong> X11 / KDE</li>
<li><strong>Hardware:</strong> ThinkPad</li>
</ul>
<h3>Permissions & Dependencies</h3>
<p>All verified working:</p>
Check | Result
-- | --
/dev/kvm | accessible, user in kvm group
/dev/fuse | crw-rw-rw- root root 10, 229
uidmap package | installed
/etc/subuid | bob:100000:65536
/etc/subgid | bob:100000:65536
unprivileged_userns_clone | 1
vhost_vsock module | loaded
bundled virtiofsd | ELF 64-bit, Rust, runs standalone
<h3>Steps to Reproduce</h3>
<ol>
<li>Install <code>claude-desktop</code> from official apt repo on Debian 12 (Bookworm)</li>
<li>Launch Claude Desktop</li>
<li>Open Cowork tab</li>
<li>Observe "Failed to start Claude's workspace" error</li>
</ol>
<h3>What Should Happen</h3>
<p>Cowork should start the VM and present the workspace.</p>
<h3>Relevant Log</h3>
<p>From <code>~/.config/Claude/logs/cowork_vm_node.log</code>:</p>
<pre><code>[linux-vm] Spawning helper: /usr/lib/claude-desktop/resources/cowork-linux-helper
[cowork-linux-helper] starting (pid=XXXXX, socket=/run/user/1000/claude-cowork-vm.sock)
[cowork-linux-helper] [server] listening on /run/user/1000/claude-cowork-vm.sock
[VM:steps] create_network started
[cowork-linux-helper] [virtiofsd] setgroups() failed with error=1:Operation not permitted
[VM:start] VM boot failed: virtiofsd socket: /run/user/1000/cowork-vm-XXXXXXXXXX/virtiofsd-0.sock did not appear within 5s
</code></pre>
<p>After applying seccomp mitigation for setgroups:</p>
<pre><code>[VM:steps] create_network started
[cowork-linux-helper] [virtiofsd] fuse: invalid argument `/run/user/1000/cowork-vm-XXXXXXXXXX/virtiofsd-0.sock'
[VM:start] VM boot failed: virtiofsd socket did not appear within 5s
</code></pre>
<h3>Related Issues</h3>
<ul>
<li><a href="https://github.com/lima-vm/lima/discussions/1849">lima-vm/lima#1849</a> -- identical <code>setgroups()</code> error with virtiofsd in user namespaces</li>
<li><a href="https://github.com/anthropics/claude-code/issues/74605">#74605</a> -- virtiofsd probe path issues on non-Ubuntu distros</li>
</ul>
<h3>Suggested Fix</h3>
<p>The <code>cowork-linux-helper</code> needs to either:</p>
<ol>
<li>Write <code>allow</code> to <code>/proc/self/setgroups</code> inside the user namespace before spawning virtiofsd</li>
<li>Properly expose <code>/dev/fuse</code> and configure FUSE permissions within the namespace</li>
<li>Or pass <code>--sandbox=none</code> to virtiofsd when running inside the helper's namespace (the helper already provides isolation, so virtiofsd's internal sandboxing is redundant and causes the conflict)</li>
</ol>
<h3>Claude Code Version</h3>
<p>N/A -- this is a Claude Desktop issue. Package version: <code>1.22209.0</code></p>
<h3>Platform</h3>
<p>Anthropic API (official <code>.deb</code>)</p>
<h3>Operating System</h3>
<p>Debian 12 (Bookworm) -- amd64</p></body></html>### What's Wrong?
Cowork fails to start on Debian 12 (Bookworm) using the official .deb from downloads.claude.ai. The cowork-linux-helper spawns virtiofsd inside a user namespace where two syscall/permission issues prevent the socket from being created.
Error 1: setgroups() denied in user namespace
[virtiofsd] setgroups() failed with error=1:Operation not permitted
The Go helper creates a user namespace and spawns virtiofsd inside it. The setgroups() syscall is denied because /proc/self/setgroups defaults to deny in unprivileged user namespaces. This causes virtiofsd to crash before creating the socket.
This was mitigated with a compiled C wrapper around cowork-linux-helper that installs a seccomp-bpf filter returning ERRNO(0) for __NR_setgroups before exec'ing the real helper.
Error 2: FUSE invalid argument on socket path
[virtiofsd] fuse: invalid argument `/run/user/1000/cowork-vm-XXXXXXXXXX/virtiofsd-0.sock'
After mitigating the setgroups error, virtiofsd still fails with a FUSE error. The FUSE device setup inside the helper's user namespace fails, even on kernel 6.12 where user namespace FUSE support is improved. This appears to be the helper's namespace configuration not properly exposing /dev/fuse or not setting up the namespace with the right FUSE permissions.
The bundled virtiofsd works fine standalone:
/usr/lib/claude-desktop/resources/virtiofsd \
--socket-path=/tmp/test.sock \
--shared-dir=/tmp \
--sandbox=none
# Output: [INFO virtiofsd] Waiting for vhost-user socket connection...
This confirms the binary is functional -- the issue is entirely within the user namespace that cowork-linux-helper creates.
Environment
- Package: Official
.debfromdownloads.claude.ai/claude-desktop/apt/stable, version1.22209.0 - OS: Debian 12 (Bookworm), amd64
- Kernels tested: 6.1.0-50-amd64 (stock Bookworm) and 6.12.95+deb12-amd64 (bookworm-backports) -- same failure on both
- GPU: NVIDIA (proprietary driver 535.261.03, DKMS)
- Display: X11 / KDE
- Hardware: ThinkPad
Permissions & Dependencies
All verified working:
| Check | Result |
|-------|--------|
| /dev/kvm | accessible, user in kvm group |
| /dev/fuse | crw-rw-rw- root root 10, 229 |
| uidmap package | installed |
| /etc/subuid | bob:100000:65536 |
| /etc/subgid | bob:100000:65536 |
| unprivileged_userns_clone | 1 |
| vhost_vsock module | loaded |
| bundled virtiofsd | ELF 64-bit, Rust, runs standalone |
Steps to Reproduce
- Install
claude-desktopfrom official apt repo on Debian 12 (Bookworm) - Launch Claude Desktop
- Open Cowork tab
- Observe "Failed to start Claude's workspace" error
What Should Happen
Cowork should start the VM and present the workspace.
Relevant Log
From ~/.config/Claude/logs/cowork_vm_node.log:
[linux-vm] Spawning helper: /usr/lib/claude-desktop/resources/cowork-linux-helper
[cowork-linux-helper] starting (pid=XXXXX, socket=/run/user/1000/claude-cowork-vm.sock)
[cowork-linux-helper] [server] listening on /run/user/1000/claude-cowork-vm.sock
[VM:steps] create_network started
[cowork-linux-helper] [virtiofsd] setgroups() failed with error=1:Operation not permitted
[VM:start] VM boot failed: virtiofsd socket: /run/user/1000/cowork-vm-XXXXXXXXXX/virtiofsd-0.sock did not appear within 5s
After applying seccomp mitigation for setgroups:
[VM:steps] create_network started
[cowork-linux-helper] [virtiofsd] fuse: invalid argument `/run/user/1000/cowork-vm-XXXXXXXXXX/virtiofsd-0.sock'
[VM:start] VM boot failed: virtiofsd socket did not appear within 5s
Related Issues
- [lima-vm/lima#1849](https://github.com/lima-vm/lima/discussions/1849) -- identical
setgroups()error with virtiofsd in user namespaces - [#74605](https://github.com/anthropics/claude-code/issues/74605) -- virtiofsd probe path issues on non-Ubuntu distros
Suggested Fix
The cowork-linux-helper needs to either:
- Write
allowto/proc/self/setgroupsinside the user namespace before spawning virtiofsd - Properly expose
/dev/fuseand configure FUSE permissions within the namespace - Or pass
--sandbox=noneto virtiofsd when running inside the helper's namespace (the helper already provides isolation, so virtiofsd's internal sandboxing is redundant and causes the conflict)
Claude Code Version
N/A -- this is a Claude Desktop issue. Package version: 1.22209.0
Platform
Anthropic API (official .deb)
Operating System
Debian 12 (Bookworm) -- amd64
What Should Happen?
Cowork should start the VM and present the workspace. The bundled virtiofsd binary is functional and the host has a complete, working KVM stack. The failure is entirely within the user namespace that cowork-linux-helper creates -- the namespace setup needs to handle setgroups and FUSE permissions correctly on Debian, not just Ubuntu.
Error Messages/Logs
Primary error (setgroups):
[VM:steps] create_network started
[cowork-linux-helper] [virtiofsd] setgroups() failed with error=1:Operation not permitted
[VM:start] VM boot failed: virtiofsd socket: /run/user/1000/cowork-vm-806668739/virtiofsd-0.sock did not appear within 5s
Secondary error (after mitigating setgroups with seccomp-bpf wrapper on cowork-linux-helper):
[VM:steps] create_network started
[cowork-linux-helper] [virtiofsd] fuse: invalid argument `/run/user/1000/cowork-vm-2375518118/virtiofsd-0.sock'
[VM:start] VM boot failed: virtiofsd socket did not appear within 5s
Standalone virtiofsd test (works fine outside the helper's namespace):
$ /usr/lib/claude-desktop/resources/virtiofsd --socket-path=/tmp/test.sock --shared-dir=/tmp --sandbox=none
[INFO virtiofsd] Waiting for vhost-user socket connection...
Full log: ~/.config/Claude/logs/cowork_vm_node.log
Steps to Reproduce
- Install
claude-desktopfrom official apt repo (downloads.claude.ai/claude-desktop/apt/stable) on Debian 12 (Bookworm) - Ensure KVM stack is working: user in
kvmgroup,/dev/kvmaccessible,/dev/fuseaccessible,uidmapinstalled, subuid/subgid configured - Launch Claude Desktop
- Open the Cowork tab
- Observe "Failed to start Claude's workspace" with
virtiofsd socket did not appear within 5s
Note: Tested on both kernel 6.1.0-50 (stock Bookworm) and 6.12.95 (bookworm-backports). Same failure on both. The bundled virtiofsd at /usr/lib/claude-desktop/resources/virtiofsd works perfectly when run standalone outside the helper's user namespace.
Claude Model
Not sure / Multiple models
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
Package version: 1.22209.0
Platform
Anthropic API
Operating System
Ubuntu/Debian Linux
Terminal/Shell
Non-interactive/CI environment
Additional Information
Full cowork_vm_node.log attached below (username sanitized to /home/user/).
Mitigations attempted (none fully resolved):
- Kernel upgrade from 6.1.0-50 to 6.12.95 (bookworm-backports)
- Installing
uidmappackage - Setting
cap_setgid,cap_setuidon virtiofsd and cowork-linux-helper - SUID on both binaries
- LD_PRELOAD with a
setgroups()shim (stripped by the Go helper) - Shell script wrapper around virtiofsd (helper detects non-ELF and skips it)
- Compiled C wrapper injecting
--sandbox=noneto virtiofsd (helper never calls wrapper -- thefuse: invalid argumentis from the namespace setup, not virtiofsd's own sandbox) - Compiled C seccomp-bpf wrapper around cowork-linux-helper intercepting
__NR_setgroups-- this fixed the setgroups error but exposed the secondary FUSE error
Related issues:
- lima-vm/lima#1849 -- identical
setgroups()error with virtiofsd in user namespaces - #74605 -- virtiofsd probe path issues on non-Ubuntu distros (by aaddrick, maintainer of claude-desktop-debian)
Sanitized Log:
Root Cause Found
The issue was not a user namespace or kernel problem. The cowork-linux-helper
resolves virtiofsd from the system PATH, and on Debian 12 with qemu-system-x86
installed, /usr/bin/virtiofsd is the old C QEMU virtiofsd -- not the bundled
Rust version at /usr/lib/claude-desktop/resources/virtiofsd.
The old C virtiofsd has incompatible CLI syntax and calls setgroups() in its
sandbox setup, which fails in user namespaces. This produced both errors described
above:
setgroups() failed-- the old C virtiofsd's sandbox calling setgroupsfuse: invalid argument-- the old C virtiofsd not understanding the Rust
virtiofsd's CLI arguments
Confirmed via strace: the process loading libseccomp.so, libcap-ng.so, libglib-2.0.so (C virtiofsd dependencies) instead of the statically-linked
Rust binary.
Workaround
sudo ln -sf /usr/lib/claude-desktop/resources/virtiofsd /usr/bin/virtiofsd
This makes the probe at /usr/bin/virtiofsd resolve to the bundled Rust version.
Cowork starts successfully after this.
Suggested Fix
This is the same class of issue as #74605. The client should either:
- Always prefer the bundled virtiofsd over any system binary
- Or validate the resolved binary (e.g. check
virtiofsd --versionoutput
for the Rust version string) before using it
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗