[BUG] Cowork readiness probe hardcodes Debian OVMF/virtiofsd paths → yukonSilver unsupported on Arch/Fedora (fix included)
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?
Summary
On a CachyOS (Arch-based) system with a fully functional QEMU/KVM virtualization stack — confirmed via direct testing, not assumption — Claude Desktop's Cowork tab never successfully starts a VM. The cowork-linux-helper process spawns cleanly and binds its control socket on every single launch, proving the local virtualization dependency chain works. Immediately after, the platform-support gate yukonSilver reports status=unsupported, the session is torn down, and the cycle repeats on next launch with no VM ever booting.
This matches a long-documented bug pattern (yukonSilver not supported) reported extensively on Windows across many GitHub issues, where the gate is a remote feature-flag evaluation (GrowthBook) rather than a genuine local hardware check — meaning it can produce false negatives independent of actual system capability. This report documents what appears to be the same bug class occurring on Linux, likely a new/under-reported surface for it.
Environment
Distro: CachyOS (Arch Linux based), fish shell
Kernel: 7.1.2-3-cachyos
CPU: AMD Ryzen 7 3700X (16 threads) @ 4.43 GHz
Motherboard: MSI MPG X570 GAMING EDGE WIFI (MS-7C37)
GPU: NVIDIA GeForce GTX 1080 Ti (proprietary driver)
QEMU: QEMU emulator version 11.0.2
Claude Desktop install source: CachyOS native repo package (pacman -S claude-desktop), not the .deb/AUR path
Claude Desktop version: 1.17377.1-1
Install location: /usr/lib/claude-desktop/
Config/log root: ~/.config/Claude/
What was verified working before filing this
To rule out the obvious local-system causes first:
Hardware virtualization support confirmed at CPU level. grep -w svm /proc/cpuinfo initially came back with all AMD-V sub-feature bits present (svm_lock, nrip_save, npt, avic, etc.) but the bare svm enablement flag missing — consistent with the SVMDIS bit being set in VM_CR (MSR 0xC0010114), which happens when AMD-V/SVM Mode is disabled in firmware even though the silicon supports it.
Root cause was BIOS-level, not OS-level. Enabled SVM Mode in the MSI Click BIOS 5 menu (OC → CPU Features → SVM Mode). Confirmed post-reboot: svm now appears standalone in /proc/cpuinfo.
KVM module loads and functions correctly:
sudo modprobe kvm_amd
ls /dev/kvm
→ crw-rw-rw- 10,232 root ... /dev/kvm
QEMU itself is fully functional (qemu-system-x86_64 --version returns cleanly, package installed via qemu-desktop, edk2-ovmf, virtiofsd).
A red herring was ruled out: Mesa loader logged MESA-LOADER: failed to open dri: /usr/lib/gbm/dri_gbm.so: cannot open shared object file: Permission denied. Investigation via strace -f -e trace=open,openat,access showed this was Chromium's seccomp-bpf sandbox trapping the GPU process's direct syscall (SIGSYS/SYS_SECCOMP) and successfully proxying it through the sandbox broker (openat(...) = 257, valid fd returned). The file has correct root:root 755 permissions; no AppArmor is active on this system (cat /sys/kernel/security/lsm → capability,landlock,lockdown,yama,bpf, no MAC layer present); / is a standard rw btrfs mount with no noexec. This error is cosmetic Mesa DRI-backend probing noise, unrelated to Cowork's VM path (GBM is Wayland/DRM-specific; testing was also done under --ozone-platform=x11).
Conclusion: the local virtualization and sandboxing stack is fully operational. The failure is downstream of all of this.
Reproduction steps
Install claude-desktop on CachyOS via the native repo package.
Complete the above local virtualization setup (BIOS SVM enable, KVM module load, QEMU/OVMF/virtiofsd install).
Launch Claude Desktop, sign in normally (OAuth/token cache confirmed loading correctly in main.log).
Attempt to open the Cowork tab.
Observe: workspace never initializes; a "QEMU requirement" style warning is intermittently shown in the UI, but the underlying log shows a distinct, more specific failure (below).
Actual behavior (from ~/.config/Claude/logs/cowork_vm_node.log)
Every attempt follows the identical pattern — helper spawns, socket listens, gate rejects, cleanup, retry a few minutes later, indefinitely:
2026-07-02 05:21:04 [info] [cleanupVMBundleIfUnsupported] yukonSilver not supported (status=unsupported), checking for stale bundle...
2026-07-02 05:26:01 [info] [VM] Loading vmClient (TypeScript) module...
2026-07-02 05:26:01 [info] [VM] Module loaded successfully
2026-07-02 05:26:02 [info] [linux-vm] Spawning helper: /usr/lib/claude-desktop/resources/cowork-linux-helper
2026-07-02 05:26:02 [info] [linux-vm-helper] [cowork-linux-helper] 2026/07/02 05:26:02.297220 starting (pid=13825, socket=/run/user/1000/claude-cowork-vm.sock)
[cowork-linux-helper] 2026/07/02 05:26:02.297351 [server] listening on /run/user/1000/claude-cowork-vm.sock
2026-07-02 05:28:35 [warn] [linux-vm] Helper exited (code=null, signal=SIGHUP)
2026-07-02 05:29:06 [info] [cleanupVMBundleIfUnsupported] yukonSilver not supported (status=unsupported), checking for stale bundle...
...repeating identically across at least 9 distinct launch attempts over roughly 70 minutes of active troubleshooting, every one ending the same way. Full log available on request; pattern is consistent throughout — no instance ever progresses past helper-socket-listening to an actual VM boot, disk mount, network handshake, or SDK install step.
Notably, main.log shows [growthbook] loaded 202 features (0 changed) at session start — confirming the client fetches remote feature-flag state via GrowthBook, the same system implicated in the parallel Windows bug cluster below.
Expected behavior
Given a system with hardware virtualization enabled, a functioning KVM device node, working QEMU, and a helper process that successfully spawns and binds its control socket, Cowork should proceed to download/validate the VM bundle and boot the workspace — consistent with how it behaves on macOS/Windows when their respective hypervisor backends are healthy.
Why this looks like a known bug class, not a new failure mode
The message format yukonSilver not supported (status=unsupported), checking for stale bundle... is not novel — it appears verbatim across a large, actively-tracked cluster of Windows-side GitHub issues (a non-exhaustive sample surfaced while researching this): #25136, #25325, #27406, #28238, #32004, #37016, #45140, #47327, and others cross-referenced within them.
The most diagnostically useful of these, #25325, identifies the actual mechanism on Windows: the yukonSilver GrowthBook feature flag's targeting rule depends on a client-reported can_elevate attribute. Under MSIX packaging, that attribute always evaluates false regardless of the user's real admin/elevation status (an AppContainer sandboxing artifact), so the flag incorrectly resolves to unsupported — even when the VM itself boots successfully and is confirmed working in that reporter's case. The tab is hidden by a flag evaluation bug, not a genuine capability gap.
Hypothesis for the Linux case documented here: the same class of bug — a client-reported attribute feeding the yukonSilver targeting rule is either missing, malformed, or simply not enumerated for the linux platform value at all (plausible given Cowork's Linux support is explicitly beta-labeled, and per public reverse-engineering writeups, Linux VM support only recently received its first community-contributed implementation attempt). The evidence supporting this over a genuine capability gap:
The helper process — the actual thing responsible for talking to KVM/QEMU — spawns and binds successfully every time, with zero errors of its own.
The rejection happens at a gate (cleanupVMBundleIfUnsupported) that runs before any VM bundle download or boot attempt, i.e., before any real capability could even be tested.
This is architecturally the same shape as the confirmed Windows can_elevate bug: a remote flag evaluation short-circuiting a working local stack.
Ask
Audit whether the yukonSilver GrowthBook targeting rule correctly enumerates and evaluates Linux client attributes (OS/platform string, KVM presence, or whatever the Linux equivalent of can_elevate is), given the precedent of the MSIX-specific false negative on Windows.
If Linux Cowork requires explicit beta/cohort enrollment separate from the platform capability check, surface that in-app rather than presenting a generic "QEMU requirement" warning that sends users down a hardware-troubleshooting path for what may be a flagging/rollout issue.
Consider logging the actual attribute values being evaluated by the yukonSilver flag (not just pass/fail) in cowork_vm_node.log, to save users and support staff from having to reverse-engineer the gate the way this report had to.
Steps already taken by the reporter (for triage — do not ask user to repeat these)
BIOS SVM Mode enabled, confirmed via /proc/cpuinfo
kvm_amd module loaded and persisted via /etc/modules-load.d/
/dev/kvm confirmed present with usable permissions
QEMU, OVMF, virtiofsd all installed and verified
GPU/Mesa/sandbox permission red herring fully traced and ruled out via strace
Confirmed no AppArmor/SELinux MAC layer interfering
Confirmed clean app quit behavior (no orphaned processes/stale locks holding a single-instance lock)
claude-desktop --doctor attempted per upstream aaddrick/claude-desktop-debian documentation — flag is a no-op on the CachyOS-packaged build (confirmed via --help); no diagnostic output produced
What Should Happen?
On any Linux host with a working virtualization stack — /dev/kvm accessible, vhost_vsock loaded, and QEMU + OVMF + virtiofsd installed — Cowork's readiness probe should detect those tools and evaluate yukonSilver as supported, so the VM boots. Detection should not hinge on Debian/Ubuntu-specific install paths: OVMF and virtiofsd sit at different canonical locations on other distributions (e.g. /usr/share/edk2/x64/OVMF_CODE.4m.fd and /usr/lib/virtiofsd on Arch), and the probe should resolve them there as well. Instead it returns unsupportedCode: virtualization_tools_missing while the tools are present and functional.
Error Messages/Logs
Steps to Reproduce
Steps to Reproduce
- On a non-Debian Linux distro (here: CachyOS/Arch, installed via a community repackage of the official .deb, as there is no official Arch build), install a full virtualization stack: qemu-system-x86, edk2-ovmf, virtiofsd.
- Confirm it's functional: /dev/kvm present and R/W-accessible, vhost_vsock loaded (lsmod | grep vsock), firmware and virtiofsd installed (/usr/share/edk2/x64/OVMF_CODE.4m.fd, /usr/lib/virtiofsd).
- Launch Claude Desktop, open the Cowork tab.
- The VM never boots. ~/.config/Claude/logs/cowork_vm_node.log logs yukonSilver not supported (status=unsupported) every launch; ~/.config/Claude/vm_bundles/ is never created.
- Note the mismatch: the tools are installed, but at distro-native paths the probe never checks (it looks only in /usr/share/OVMF/… and /usr/libexec | /usr/bin/virtiofsd). Full trace and fix in Additional Information.
Claude Model
_No response_
Is this a regression?
No, this never worked
Last Working Version
_No response_
Claude Code Version
2.1.195 (Claude Code)
Platform
Anthropic API
Operating System
Other Linux
Terminal/Shell
Other
Additional Information
<html><head></head><body><h2>Resolution — Root cause found & fixed (self-diagnosed)</h2>
<p><strong>TL;DR:</strong> This is <strong>not</strong> a hardware, KVM, vsock, entitlement, or distro-support problem. Cowork's Linux VM readiness probe resolves the QEMU UEFI firmware (OVMF) and <code>virtiofsd</code> binary from a <strong>hardcoded Debian/Ubuntu path list</strong>. On Arch/CachyOS both are genuinely installed, just at different canonical locations, so the probe resolves <code>firmwarePath: null</code> and <code>virtiofsdPath: null</code> and returns <code>unsupportedCode: "virtualization_tools_missing"</code> — which surfaces upstream as <code>yukonSilver: unsupported</code>. Creating compatibility symlinks at the Debian paths makes the probe pass, and the VM boots normally. <strong>No modification of <code>app.asar</code> is required.</strong></p>
<h3>The misleading symptom</h3>
<p>The line everyone chases:</p>
<pre><code>[cleanupVMBundleIfUnsupported] yukonSilver not supported (status=unsupported), checking for stale bundle...
</code></pre>
<p>This is emitted by a <strong>cleanup routine</strong>, not the gate. It calls the feature-support evaluator, sees <code>yukonSilver</code> is unsupported, and deletes any stale VM bundle. It only <em>reports</em> the verdict — it doesn't make it. This is why <code>~/.config/Claude/vm_bundles/</code> never appears: the download is never triggered because the verdict upstream is already "unsupported." Tracing this log line leads nowhere; the decision is made earlier.</p>
<h3>Actual decision path</h3>
<p><code>getSupportedFeatures()</code> → <code>yukonSilver</code> entry → a platform capability evaluator. On Linux the evaluator runs a <strong>capability probe</strong> that resolves paths and device access into a support object, then a switch maps the first failing field to an <code>unsupportedCode</code>. The relevant branch order on Linux is:</p>
<ol>
<li><code>virtualization_entitlement_missing</code> — helper binary / guest image / <code>virtiofsd</code> / peer-cred check missing</li>
<li><code>virtualization_tools_missing</code> — <strong><code>!qemuPath || !firmwarePath || !virtiofsdPath</code></strong></li>
<li><code>virtualization_not_available</code> — <code>/dev/kvm</code> missing</li>
<li><code>kvm_permission_denied</code> — <code>/dev/kvm</code> or <code>/dev/vhost-vsock</code> not R/W-accessible</li>
<li><code>vhost_vsock_module_missing</code> — <code>/dev/vhost-vsock</code> absent</li>
<li>otherwise → <code>supported</code></li>
</ol>
<p>On Arch/CachyOS, branch <strong>2</strong> fires.</p>
<h3>Root cause: Debian-first path assumptions</h3>
<p>The probe resolves each dependency by <code>access()</code>-testing a fixed candidate list and taking the first hit, else <code>null</code>:</p>
Field | Candidate paths the probe checks (x86-64) | Resolves against access()
-- | -- | --
qemuPath | searches $PATH for qemu-system-x86_64 | X_OK — found
firmwarePath | /usr/share/OVMF/OVMF_CODE_4M.fd, /usr/share/OVMF/OVMF_CODE.fd | R_OK — null on Arch
virtiofsdPath | /usr/libexec/virtiofsd, /usr/bin/virtiofsd | R_OK — null on Arch
<p><em>(Fill in exact Desktop version with <code>pacman -Qi claude-desktop</code>.)</em></p>
<h3>Fix (user-side, no app modification)</h3>
<p>Create compatibility symlinks so the probe resolves the tools that are already installed. Firmware needs both CODE and VARS (see derivation note above):</p>
<pre><code class="language-sh">sudo mkdir -p /usr/share/OVMF
sudo ln -sf /usr/share/edk2/x64/OVMF_CODE.4m.fd /usr/share/OVMF/OVMF_CODE.fd
sudo ln -sf /usr/share/edk2/x64/OVMF_VARS.4m.fd /usr/share/OVMF/OVMF_VARS.fd
sudo ln -sf /usr/lib/virtiofsd /usr/bin/virtiofsd
</code></pre>
<p>To make it declarative and survive package churn, drop the same three links into a tmpfiles unit — create <code>/etc/tmpfiles.d/cowork-arch-compat.conf</code> with:</p>
<pre><code>L+ /usr/share/OVMF/OVMF_CODE.fd - - - - /usr/share/edk2/x64/OVMF_CODE.4m.fd
L+ /usr/share/OVMF/OVMF_VARS.fd - - - - /usr/share/edk2/x64/OVMF_VARS.4m.fd
L+ /usr/bin/virtiofsd - - - - /usr/lib/virtiofsd
</code></pre>
<p>then apply with <code>sudo systemd-tmpfiles --create /etc/tmpfiles.d/cowork-arch-compat.conf</code>.</p>
<p>If <code>/dev/vhost-vsock</code> is not world-R/W (branch 4 will then trip after the path fix), add a udev rule to match the <code>/dev/kvm</code> treatment:</p>
<pre><code class="language-sh">echo 'KERNEL=="vhost-vsock", MODE="0666"' | sudo tee /etc/udev/rules.d/99-vhost-vsock.rules
sudo udevadm control --reload-rules && sudo udevadm trigger --name-match=vhost-vsock
</code></pre>
<p>Verify the links resolve, then restart Claude Desktop and watch <code>~/.config/Claude/logs/cowork_vm_node.log</code>: the <code>yukonSilver not supported</code> line disappears and the VM bundle promote/boot sequence begins. <strong>Confirmed working</strong> — Cowork boots its QEMU/KVM VM on CachyOS with the sandbox fully intact.</p>
<h3>Suggested upstream fix</h3>
<p>The Linux VM capability is fully present on non-Debian distros; <strong>only path detection blocks it.</strong> Options, in rough order of robustness:</p>
<ol>
<li><strong>Use QEMU's firmware descriptors.</strong> QEMU ships distro-agnostic JSON descriptors at <code>/usr/share/qemu/firmware/*.json</code> that map firmware to their actual on-disk <code>OVMF_CODE</code>/<code>OVMF_VARS</code> paths (the same mechanism libvirt uses for firmware autoselection). Consulting these resolves OVMF correctly on every distro without a hardcoded list.</li>
<li><strong>Widen the candidate lists.</strong> Add at minimum <code>/usr/share/edk2/x64/OVMF_CODE.4m.fd</code> (Arch/Fedora) for firmware and <code>/usr/lib/virtiofsd</code> for virtiofsd; resolve <code>virtiofsd</code> via <code>$PATH</code> as is already done for <code>qemu-system-*</code>.</li>
<li><strong>Honor packager/user overrides.</strong> Environment variables (e.g. <code>COWORK_OVMF_CODE</code> / <code>COWORK_OVMF_VARS</code> / <code>COWORK_VIRTIOFSD</code>) would let repackagers for unsupported distros bridge the gap without patching <code>app.asar</code>.</li>
</ol>
<p>Any of these would let the existing, working Linux VM path light up on Arch/Fedora/etc. — relevant to #65697 (official broader-Linux support), since the remaining gap for these platforms is dependency-path detection, not VM capability.</p>
<h3>Note on the corroborating Ubuntu case</h3>
<p>This fix addresses the <strong>non-Debian path class</strong> specifically. A <code>yukonSilver: unsupported</code> on Ubuntu/Debian (#72741) — where these paths <em>are</em> correct — is a separate diagnosis (e.g. <code>virtiofsd</code>/OVMF package genuinely absent, the native-module/entitlement branch, or actual KVM/vsock access). The evaluator's per-branch <code>unsupportedCode</code> is the datum to pull there; it is emitted in the <code>lam_feature_support_evaluated</code> telemetry event but not written to the text logs. A <code>--doctor</code>/readiness command that prints the resolved support object and its <code>unsupportedCode</code> would make all of these self-serviceable.</p></body></html>
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗