Bug Report: Linux sandbox fails to start on Windows 10 (RPC pipe closed) — MSIX identity detection bug
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?
Title
Claude Desktop 1.40609.0 on Windows 10 22H2: Linux sandbox never starts ("RPC pipe closed") because the app reads package identity via WinRT Package::Current() (returns empty) while the process does have a valid MSIX package identity.
Environment
- OS: Windows 10 Pro, build 19045 (22H2)
- Claude Desktop version: 1.40609.0 (MSIX, installed via Store)
- Package full name:
Claude_1.40609.0.0_x64__pzs8sxrjxfjjc - Package family name:
Claude_pzs8sxrjxfjjc - WSL: 2.7.12 (but the sandbox is not a WSL distro — LxssManager stays Stopped, which is expected)
- CLI binary downloaded by the app:
claude-code2.1.247 (253 MB standalone exe)
Symptom
Any attempt to run a shell command in the sandbox fails immediately with:
Workspace unavailable. The isolated Linux environment failed to start (RPC pipe closed)
Failed to start Claude's workspace / RPC pipe closed
This has reproduced since first install (2026-08-30 14:52) and across multiple full reboots. The VM image is fully downloaded (rootfs.vhdx ~7.9 GB present), the package registration status is Ok, and all virtualization features (Subsystem-Linux / VirtualMachinePlatform / Hyper-V-Hypervisor) are Enabled. Re-registering the package and reinstalling do not help.
Root cause (two compounding bugs)
Bug 1 — the app reads package identity through the wrong API and gets empty
In main.log, every msix_identity_source is native_empty (54 occurrences, zero exceptions), and each MsixSpawnDiag session starts with identity_source=native_empty.
From unpacking app.asar, the identity lookup is:
function tOt() {
if (QDt) return gD;
if (QDt = true, Br()) {
try {
let e = (eOt ?? require("@ant/claude-native")).getCurrentPackageFamilyName();
if ($Dt = e ? native_ok : native_empty, e) {
return gD = e, P.info([MSIX] Package family from native API: %s, e), gD
}
} catch {
$Dt = native_unavailable,
P.info([MSIX] Native API unavailable, falling back to exe path parsing)
}
return gD = Nce(), gD ? P.info([MSIX] Package family from exe path: %s, gD) : P.warn([MSIX] Could not determine package family name), gD
}
...
}
So the native binding @ant/claude-native (claude-native-binding.node, Rust, built against the windows-0.58.0 crate) calls WinRT Package::Current(), and on this machine that returns an empty string without throwing — which is why native_empty is recorded and the exe-path fallback is never taken.
The decisive contrast (the "process has identity but the app can't read it" evidence):
- Calling Win32
GetPackageFullNameon the same runningclaude.exeprocess returns the correct identity:Claude_1.40609.0.0_x64__pzs8sxrjxfjjc(verified via Python ctypes against every live claude process). - The AppModel-Runtime/Admin event log shows the normal
[LaunchProcess]+ "process added to desktop AppX container for package Claude…" events. - In the same
main.log, the exe-path-based fallback does resolve:[MSIX] Package family from exe path: Claude_pzs8sxrjxfjjcand[MSIX] Filesystem virtualization active — …\LocalCache\Roaming\Claude-3p exists.
So the process genuinely has a valid MSIX identity; only the WinRT Package::Current() path returns empty. On this Windows 10 build that API path is apparently unreliable (in a test harness, Package::Current() raises HRESULT 0x80073D54 "该进程没有程序包标识符" even for the packaged process).
Bug 2 — cowork-svc verifies the downloaded CLI child process, which has no package identity
cowork-svc.exe validates the pipe client using GetNamedPipeClientProcessId + GetPackageFamilyName. But when running a sandbox command, Claude spawns a separately downloaded CLI binary:
C:\Users\daixi\AppData\Local\Claude-3p\claude-code\2.1.247\claude.exe (cli_binary_source: 'required_version')
That exe lives outside the MSIX package and has no package identity, so cowork-svc sees client package: "", fails the signature/identity check, and closes the pipe → RPC pipe closed.
A related tell: the updater's identity check is also heuristic, not authoritative:
[updater] MSIX detected: windowsStore=false, appPathMatch=true, source=appPath,
exe=C:\Program Files\WindowsApps\Claude_...\app\claude.exe
i.e. it infers "is MSIX" from a path-string match, consistent with the native identity check being unreliable.
Impact / what I've already ruled out
- Re-registering the package (
Add-AppxPackage -DisableDevelopmentMode -Register), the in-app "Repair", a fresh user account, and full reinstalls all do not fix it (this matches a product bug, not a local-config problem). - No VMware/VirtualBox/emulator, no competing hypervisor, healthy
vmcompute/HvHost/WSLService. - A hijacked
Claude.lnkin the Start Menu (ACL containing aCodexSandboxUsersgroup, pointing directly atWindowsApps\...\claude.exe) was initially suspected and removed — it is a red herring, not the cause.
Requested fix
- Make the MSIX identity lookup fall back to Win32
GetPackageFullName(or treat an empty WinRTPackage::Current()result as "unavailable" and take the exe-path/native fallback), rather than recordingnative_emptyand giving up. - Have
cowork-svcverify the identity of the main app process (or otherwise account for the fact that the spawned CLI child process legitimately has no package identity), instead of rejecting the pipe client when its package family is empty.
Attachments I can provide on request
- Full
main.logwith allmsix_identity_source/MsixSpawnDiaglines (54 ×native_empty). cowork_vm_node.logshowing thesignature verification failed/client package: ""sequence leading toERR_VM_PIPE_CLOSED.Get-AppxPackage -Name *Claude*output (Status Ok, SignatureKind, InstallLocation).- The relevant decompiled
app.asarsnippet and the Win32GetPackageFullNameprobe output proving the process does have identity.
What Should Happen?
Title
Claude Desktop 1.40609.0 on Windows 10 22H2: Linux sandbox never starts ("RPC pipe closed") because the app reads package identity via WinRT Package::Current() (returns empty) while the process does have a valid MSIX package identity.
Environment
- OS: Windows 10 Pro, build 19045 (22H2)
- Claude Desktop version: 1.40609.0 (MSIX, installed via Store)
- Package full name:
Claude_1.40609.0.0_x64__pzs8sxrjxfjjc - Package family name:
Claude_pzs8sxrjxfjjc - WSL: 2.7.12 (but the sandbox is not a WSL distro — LxssManager stays Stopped, which is expected)
- CLI binary downloaded by the app:
claude-code2.1.247 (253 MB standalone exe)
Symptom
Any attempt to run a shell command in the sandbox fails immediately with:
Workspace unavailable. The isolated Linux environment failed to start (RPC pipe closed)
Failed to start Claude's workspace / RPC pipe closed
This has reproduced since first install (2026-08-30 14:52) and across multiple full reboots. The VM image is fully downloaded (rootfs.vhdx ~7.9 GB present), the package registration status is Ok, and all virtualization features (Subsystem-Linux / VirtualMachinePlatform / Hyper-V-Hypervisor) are Enabled. Re-registering the package and reinstalling do not help.
Root cause (two compounding bugs)
Bug 1 — the app reads package identity through the wrong API and gets empty
In main.log, every msix_identity_source is native_empty (54 occurrences, zero exceptions), and each MsixSpawnDiag session starts with identity_source=native_empty.
From unpacking app.asar, the identity lookup is:
function tOt() {
if (QDt) return gD;
if (QDt = true, Br()) {
try {
let e = (eOt ?? require("@ant/claude-native")).getCurrentPackageFamilyName();
if ($Dt = e ? native_ok : native_empty, e) {
return gD = e, P.info([MSIX] Package family from native API: %s, e), gD
}
} catch {
$Dt = native_unavailable,
P.info([MSIX] Native API unavailable, falling back to exe path parsing)
}
return gD = Nce(), gD ? P.info([MSIX] Package family from exe path: %s, gD) : P.warn([MSIX] Could not determine package family name), gD
}
...
}
So the native binding @ant/claude-native (claude-native-binding.node, Rust, built against the windows-0.58.0 crate) calls WinRT Package::Current(), and on this machine that returns an empty string without throwing — which is why native_empty is recorded and the exe-path fallback is never taken.
The decisive contrast (the "process has identity but the app can't read it" evidence):
- Calling Win32
GetPackageFullNameon the same runningclaude.exeprocess returns the correct identity:Claude_1.40609.0.0_x64__pzs8sxrjxfjjc(verified via Python ctypes against every live claude process). - The AppModel-Runtime/Admin event log shows the normal
[LaunchProcess]+ "process added to desktop AppX container for package Claude…" events. - In the same
main.log, the exe-path-based fallback does resolve:[MSIX] Package family from exe path: Claude_pzs8sxrjxfjjcand[MSIX] Filesystem virtualization active — …\LocalCache\Roaming\Claude-3p exists.
So the process genuinely has a valid MSIX identity; only the WinRT Package::Current() path returns empty. On this Windows 10 build that API path is apparently unreliable (in a test harness, Package::Current() raises HRESULT 0x80073D54 "该进程没有程序包标识符" even for the packaged process).
Bug 2 — cowork-svc verifies the downloaded CLI child process, which has no package identity
cowork-svc.exe validates the pipe client using GetNamedPipeClientProcessId + GetPackageFamilyName. But when running a sandbox command, Claude spawns a separately downloaded CLI binary:
C:\Users\daixi\AppData\Local\Claude-3p\claude-code\2.1.247\claude.exe (cli_binary_source: 'required_version')
That exe lives outside the MSIX package and has no package identity, so cowork-svc sees client package: "", fails the signature/identity check, and closes the pipe → RPC pipe closed.
A related tell: the updater's identity check is also heuristic, not authoritative:
[updater] MSIX detected: windowsStore=false, appPathMatch=true, source=appPath,
exe=C:\Program Files\WindowsApps\Claude_...\app\claude.exe
i.e. it infers "is MSIX" from a path-string match, consistent with the native identity check being unreliable.
Impact / what I've already ruled out
- Re-registering the package (
Add-AppxPackage -DisableDevelopmentMode -Register), the in-app "Repair", a fresh user account, and full reinstalls all do not fix it (this matches a product bug, not a local-config problem). - No VMware/VirtualBox/emulator, no competing hypervisor, healthy
vmcompute/HvHost/WSLService. - A hijacked
Claude.lnkin the Start Menu (ACL containing aCodexSandboxUsersgroup, pointing directly atWindowsApps\...\claude.exe) was initially suspected and removed — it is a red herring, not the cause.
Requested fix
- Make the MSIX identity lookup fall back to Win32
GetPackageFullName(or treat an empty WinRTPackage::Current()result as "unavailable" and take the exe-path/native fallback), rather than recordingnative_emptyand giving up. - Have
cowork-svcverify the identity of the main app process (or otherwise account for the fact that the spawned CLI child process legitimately has no package identity), instead of rejecting the pipe client when its package family is empty.
Attachments I can provide on request
- Full
main.logwith allmsix_identity_source/MsixSpawnDiaglines (54 ×native_empty). cowork_vm_node.logshowing thesignature verification failed/client package: ""sequence leading toERR_VM_PIPE_CLOSED.Get-AppxPackage -Name *Claude*output (Status Ok, SignatureKind, InstallLocation).- The relevant decompiled
app.asarsnippet and the Win32GetPackageFullNameprobe output proving the process does have identity.
Error Messages/Logs
Steps to Reproduce
Title
Claude Desktop 1.40609.0 on Windows 10 22H2: Linux sandbox never starts ("RPC pipe closed") because the app reads package identity via WinRT Package::Current() (returns empty) while the process does have a valid MSIX package identity.
Environment
- OS: Windows 10 Pro, build 19045 (22H2)
- Claude Desktop version: 1.40609.0 (MSIX, installed via Store)
- Package full name:
Claude_1.40609.0.0_x64__pzs8sxrjxfjjc - Package family name:
Claude_pzs8sxrjxfjjc - WSL: 2.7.12 (but the sandbox is not a WSL distro — LxssManager stays Stopped, which is expected)
- CLI binary downloaded by the app:
claude-code2.1.247 (253 MB standalone exe)
Symptom
Any attempt to run a shell command in the sandbox fails immediately with:
Workspace unavailable. The isolated Linux environment failed to start (RPC pipe closed)
Failed to start Claude's workspace / RPC pipe closed
This has reproduced since first install (2026-08-30 14:52) and across multiple full reboots. The VM image is fully downloaded (rootfs.vhdx ~7.9 GB present), the package registration status is Ok, and all virtualization features (Subsystem-Linux / VirtualMachinePlatform / Hyper-V-Hypervisor) are Enabled. Re-registering the package and reinstalling do not help.
Root cause (two compounding bugs)
Bug 1 — the app reads package identity through the wrong API and gets empty
In main.log, every msix_identity_source is native_empty (54 occurrences, zero exceptions), and each MsixSpawnDiag session starts with identity_source=native_empty.
From unpacking app.asar, the identity lookup is:
function tOt() {
if (QDt) return gD;
if (QDt = true, Br()) {
try {
let e = (eOt ?? require("@ant/claude-native")).getCurrentPackageFamilyName();
if ($Dt = e ? native_ok : native_empty, e) {
return gD = e, P.info([MSIX] Package family from native API: %s, e), gD
}
} catch {
$Dt = native_unavailable,
P.info([MSIX] Native API unavailable, falling back to exe path parsing)
}
return gD = Nce(), gD ? P.info([MSIX] Package family from exe path: %s, gD) : P.warn([MSIX] Could not determine package family name), gD
}
...
}
So the native binding @ant/claude-native (claude-native-binding.node, Rust, built against the windows-0.58.0 crate) calls WinRT Package::Current(), and on this machine that returns an empty string without throwing — which is why native_empty is recorded and the exe-path fallback is never taken.
The decisive contrast (the "process has identity but the app can't read it" evidence):
- Calling Win32
GetPackageFullNameon the same runningclaude.exeprocess returns the correct identity:Claude_1.40609.0.0_x64__pzs8sxrjxfjjc(verified via Python ctypes against every live claude process). - The AppModel-Runtime/Admin event log shows the normal
[LaunchProcess]+ "process added to desktop AppX container for package Claude…" events. - In the same
main.log, the exe-path-based fallback does resolve:[MSIX] Package family from exe path: Claude_pzs8sxrjxfjjcand[MSIX] Filesystem virtualization active — …\LocalCache\Roaming\Claude-3p exists.
So the process genuinely has a valid MSIX identity; only the WinRT Package::Current() path returns empty. On this Windows 10 build that API path is apparently unreliable (in a test harness, Package::Current() raises HRESULT 0x80073D54 "该进程没有程序包标识符" even for the packaged process).
Bug 2 — cowork-svc verifies the downloaded CLI child process, which has no package identity
cowork-svc.exe validates the pipe client using GetNamedPipeClientProcessId + GetPackageFamilyName. But when running a sandbox command, Claude spawns a separately downloaded CLI binary:
C:\Users\daixi\AppData\Local\Claude-3p\claude-code\2.1.247\claude.exe (cli_binary_source: 'required_version')
That exe lives outside the MSIX package and has no package identity, so cowork-svc sees client package: "", fails the signature/identity check, and closes the pipe → RPC pipe closed.
A related tell: the updater's identity check is also heuristic, not authoritative:
[updater] MSIX detected: windowsStore=false, appPathMatch=true, source=appPath,
exe=C:\Program Files\WindowsApps\Claude_...\app\claude.exe
i.e. it infers "is MSIX" from a path-string match, consistent with the native identity check being unreliable.
Impact / what I've already ruled out
- Re-registering the package (
Add-AppxPackage -DisableDevelopmentMode -Register), the in-app "Repair", a fresh user account, and full reinstalls all do not fix it (this matches a product bug, not a local-config problem). - No VMware/VirtualBox/emulator, no competing hypervisor, healthy
vmcompute/HvHost/WSLService. - A hijacked
Claude.lnkin the Start Menu (ACL containing aCodexSandboxUsersgroup, pointing directly atWindowsApps\...\claude.exe) was initially suspected and removed — it is a red herring, not the cause.
Requested fix
- Make the MSIX identity lookup fall back to Win32
GetPackageFullName(or treat an empty WinRTPackage::Current()result as "unavailable" and take the exe-path/native fallback), rather than recordingnative_emptyand giving up. - Have
cowork-svcverify the identity of the main app process (or otherwise account for the fact that the spawned CLI child process legitimately has no package identity), instead of rejecting the pipe client when its package family is empty.
Attachments I can provide on request
- Full
main.logwith allmsix_identity_source/MsixSpawnDiaglines (54 ×native_empty). cowork_vm_node.logshowing thesignature verification failed/client package: ""sequence leading toERR_VM_PIPE_CLOSED.Get-AppxPackage -Name *Claude*output (Status Ok, SignatureKind, InstallLocation).- The relevant decompiled
app.asarsnippet and the Win32GetPackageFullNameprobe output proving the process does have identity.
Claude Model
None
Is this a regression?
No, this never worked
Last Working Version
_No response_
Claude Code Version
2.1.251 (Claude Code)
Platform
Anthropic API
Operating System
Windows
Terminal/Shell
Terminal.app (macOS)
Additional Information
_No response_
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗