Windows Desktop 26.721.4979.0: Code Integrity blocks bundled `vk_swiftshader.dll` inside the MSIX container, app is killed ~20s after launch (no Crashpad dump)
What version of the Codex App are you using?
26.721.4979.0 (Microsoft Store MSIX package OpenAI.Codex_26.721.4979.0_x64__2p2nqsd0c76g0).
The "About Codex" dialog is unreachable because the app never stays open long enough; version taken from Get-AppxPackage.
What subscription do you have?
Pro.
What platform is your computer?
Microsoft Windows NT 10.0.26200.0 x64
Windows 11 Home, 25H2, build 26200.8875.
What issue are you seeing?
Codex Desktop launches, shows its process tree, then is terminated roughly 20 seconds later. No Crashpad .dmp is produced and no Application error / WER event is logged — the process is killed by the platform rather than crashing.
Windows Code Integrity logs this on every launch (Microsoft-Windows-CodeIntegrity/Operational, Event ID 3033):
Code Integrity determined that a process
(\Device\HarddiskVolume3\Program Files\WindowsApps\OpenAI.Codex_26.721.4979.0_x64__2p2nqsd0c76g0\app\ChatGPT.exe)
attempted to load
\Device\HarddiskVolume3\Program Files\WindowsApps\OpenAI.Codex_26.721.4979.0_x64__2p2nqsd0c76g0\app\vk_swiftshader.dll
that did not meet the Microsoft signing level requirements.
Immediately afterwards the package status flips to Modified, NeedsRemediation, and Windows enters an auto-remediation loop — re-staging and re-registering the package after each failed launch (13 Stage/Register operations between 08:49 and 12:59 on the day this was captured).
Key isolation result
Copying the exact same payload out of C:\Program Files\WindowsApps\...\app to an ordinary directory and running ChatGPT.exe from there works correctly:
| Run | Result |
|---|---|
| Packaged (MSIX, via AUMID) | Killed ~20s in, CI 3033 block on vk_swiftshader.dll |
| Unpackaged copy, --disable-gpu --disable-software-rasterizer | Survived, 4 processes, no CI blocks |
| Unpackaged copy, no flags (control) | Survived, 9 processes / full GPU path, no CI blocks |
The no-flags control is the important one: GPU acceleration is not the variable. The same bits run fine with the normal GPU path outside the package. The failure is specific to executing inside the MSIX/AppX container, where the sandboxed child process is subject to Microsoft-signed-only binary enforcement that the bundled SwiftShader DLL cannot satisfy.
Regression window
Deployment history from Microsoft-Windows-AppXDeploymentServer/Operational:
| Deployed | Version | Outcome |
|---|---|---|
| 07-21 12:47 | 26.715.8383.0 | worked |
| 07-22 12:48 | 26.715.10079.0 | worked |
| 07-24 13:41 | 26.721.3996.0 | worked (2 days, zero CI blocks) |
| 07-25 14:04 | 26.721.4979.0 | broken |
26.721.4979.0 was staged 07-25 14:04; the first launch after it was 07-26 08:46, which is exactly when the CI 3033 blocks begin. There are no vk_swiftshader.dll blocks anywhere earlier in the retained log (back to 07-14). No Windows update, GPU driver change, or Code Integrity policy change occurred on this machine in that window — the latest OS update was 07-16 and no WDAC policy file changed.
What steps can reproduce the bug?
- On Windows 11 25H2 (build
26200.8875), install Codex Desktop26.721.4979.0from the Microsoft Store. - Launch it normally (Start menu / AUMID
OpenAI.Codex_2p2nqsd0c76g0!App). - The window appears, then the process tree is terminated ~20s later.
- Check
Microsoft-Windows-CodeIntegrity/Operationalfor Event ID 3033 namingvk_swiftshader.dll. - Check
Get-AppxPackage OpenAI.Codex— status is nowModified, NeedsRemediation.
What is the expected behavior?
The app should stay open. The bundled SwiftShader/Vulkan binaries should either be loadable under the container's signing-level enforcement, or not be loaded at all when hardware acceleration is available.
Additional information
Not a duplicate of #28909. That report (June, 26.611.8604.0) produced a Crashpad .dmp on every launch and was unaffected by --disable-gpu / --use-angle=swiftshader. Here there is no dump at all, the termination is done by Code Integrity, and the unpackaged control run shows GPU flags are irrelevant.
Diagnostics tried:
winget repair --name "ChatGPT"— succeeded, re-downloaded all 9,541 payload files and cleared theModifiedflag. The next launch re-tripped it. Repair is not a durable fix.Add-AppxPackage -Register <AppxManifest.xml>— deployment succeeded but did not clear the flag (it rebuilds registration without re-verifying file content).- Unpackaged execution — works, as above.
Security configuration (to preempt the obvious question — this machine is not locked down):
| Setting | Value |
|---|---|
| Smart App Control | Off (VerifiedAndReputablePolicyState: 0) |
| Usermode WDAC enforcement | Off (UsermodeCodeIntegrityPolicyEnforcementStatus: 0) |
| VBS / HVCI | Running |
For comparison, chrome.exe logs the identical 3033 event for its own vulkan-1.dll on this machine and continues running normally — Chrome degrades gracefully where Codex Desktop does not.
Hardware:
- CPU: Intel Core Ultra 9 275HX
- GPU: NVIDIA GeForce RTX 5090 Laptop (driver
32.0.15.9201) + Intel Graphics (driver32.0.101.8331), both healthy - RAM: 32 GB
Note that every file in the package is reported NotSigned by Authenticode (normal for MSIX, where the package is signed as a whole) — vk_swiftshader.dll is not unusual in that respect. It is simply the only one loaded by a process running under the Microsoft-signed-only mitigation.
5 Comments
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
Independent reproduction on
26.721.4979.0— plus: the package is cryptographically pristine, re-registration does NOT clear the state, and--disable-software-rasterizerdoes NOT avoid the blockSame build, same CI 3033 on
vk_swiftshader.dll, sameModified, NeedsRemediationflip. Windows 11 26200.8875, x64, zh-CN. Four additions that may help narrow this down.1. Not user-side hardening. On this machine Smart App Control is off (
VerifiedAndReputablePolicyState = 0), HVCI is off (Enabled = 0), andWin32_DeviceGuard.SecurityServicesRunningis empty. So the signing-level enforcement that kills the app is the AppX/MSIX container's own, exactly as your isolation test concluded — no third-party AV or user policy is involved. Worth stating explicitly, because the natural first guess for anyone hitting this is "your machine is locked down / your AV ate a file."2. The
Modifiedflag is spurious — the payload is byte-perfect. I verified the installed package against its ownAppxBlockMap.xml:| Check | Result |
|---|---|
| Files declared in BlockMap | 9544 |
| Present on disk, correct size | 9544 / 9544 |
| Files on disk not in BlockMap | 0 (only AppxManifest/BlockMap/Signature) |
| Per-64KB-block SHA256 over all 69
.exe/.dll/.node/.asar| all match || Package root ACL vs a healthy Store package | identical structure |
vk_swiftshader.dllitself hashes clean against the blockmap, i.e. it is exactly the DLL you shipped. SoModified, NeedsRemediationis not file tampering or corruption — it is a derived state produced by the CI kill, and it is what subsequently blocks activation entirely (0x80073CFC, "无法打开这个应用" / "This app can't open" dialog). That makes #35347 a downstream symptom of this issue rather than a separate bug — same build, same status string, and its screenshot matches what we see.3. Re-registration is not sufficient to recover (relevant to the workaround suggested in #35347). With the package in
NeedsRemediation, both of these reported success and left the flag untouched:Only re-staging the payload (Store "Repair" / Store update, which rewrites all files) clears it. Until then every activation attempt — including
Invoke-CommandInDesktopPackage— fails with0x80073CFC.4. Negative result: the obvious flag workaround does not work. After a clean repair (
Status: Ok, no leftover processes), I launched the packaged app with package identity preserved and the SwiftShader fallback explicitly disabled:Timeline (T0 = 10:25:54):
| T | Processes | New CI 3033 | Package status |
|---|---|---|---|
| +10s | 7 | 0 | Ok |
| +25s | 11 | 0 | Ok |
| +40s | 14 | 0 | Ok |
| +60s | 7 | 1 | Modified, NeedsRemediation |
CI 3033 on
vk_swiftshader.dllat 10:26:53 → AppX container destroyed at 10:26:55 → all processes gone. So--disable-software-rasterizerdoes not prevent the load inside the container; it only postponed it (59s here vs ~4 min on an unflagged launch earlier the same morning — survival time looks variable rather than flag-dependent). Sincevk_swiftshader.dllis the SwiftShader Vulkan ICD, the load is likely happening during Vulkan capability probing, which that switch doesn't gate. Users cannot work around this locally.Kill signature for anyone triaging: CI 3033 → AppX container
217 destroyed2–3 seconds later, no Application Error event, no WER, no Crashpad dump — consistent with your "killed by the platform, not crashing" observation. GreppingMicrosoft-Windows-AppModel-Runtime/Adminfor event 217 next toMicrosoft-Windows-CodeIntegrity/Operational3033 pins it in seconds.Suggested fix direction (unchanged from yours, just reinforced): ship
vk_swiftshader.dllat a signing level the AppX container accepts, or drop/gate the SwiftShader Vulkan ICD from the packaged build. Given that re-registration can't recover the resulting state, each failed launch currently costs the user a Store repair.---
Correction to my previous comment: there IS a working workaround — force ANGLE to D3D11 and disable Vulkan. Also: the GPU process is the victim, and the package version is not the variable.
I said earlier that "users cannot work around this locally." That was wrong, and the reason it was wrong points at the actual trigger. Correcting with data.
1. Working workaround (verified, 13 min clean vs 1–11 min to death before)
Launch the packaged app with package identity preserved and Vulkan disabled at the source:
| T | Processes | New CI 3033 | Package status |
|---|---|---|---|
| +15s | 12 | 0 | Ok |
| +2min | 11 | 0 | Ok |
| +5min | 9 | 0 | Ok |
| +9min | 9 | 0 | Ok |
| +13min | 9 | 0 | Ok |
Longest survival before this was 11m36s (and the three most recent unflagged/mis-flagged launches died at 5m30s, 2m14s, 1m01s). Process composition at +13min: 1 main / 4 renderer / 1 gpu-process / 2 utility / 1 crashpad-handler — the GPU process is alive and the UI is fully functional.
Note
--disable-software-rasterizeralone does not work (my earlier test: CI hit at T+59s). That switch gates the software rasterizer fallback;vk_swiftshader.dllis the SwiftShader Vulkan ICD, loaded during Vulkan ICD enumeration in GPU-process init, which that switch never reaches.--use-angle=d3d11+--disable-features=Vulkanavoids the enumeration entirely.Caveat for other users: this only helps when launched with the args, so Start-menu/taskbar activation still dies. It is args-only — no files touched, fully reversible.
2. Mechanism: the GPU process is what dies
Each failed session shows this exact sequence in the desktop log, 1 second after the CI 3033:
matched at 08:22:33, 09:26:40, 10:26:54 local — i.e. once per CI 3033 — followed by AppX container destruction (AppModel-Runtime 217) and the flip to
Modified, NeedsRemediation. So: GPU process init → Vulkan ICD enumeration → CI blocks the unsigned-for-container SwiftShader ICD → GPU process killed → relaunch fails → container torn down.3. The package version is not the variable (this may matter for your regression window)
On this machine
26.721.4979.0was installed 07-25 15:16 and then ran cleanly for 1h54m (container 210 at 15:21:12 → 217 at 17:14:56, zero CI 3033 in that window, and 8 in-app-browser sessions during it). The first CI 3033 ever recorded is 07-26 21:24:31 — ~30 hours later, after a reboot at 21:03. Every session since dies. The CodeIntegrity log on this box retains back to 06-17, so the absence of earlier blocks is real, not log rollover.Ruled out as the 07-26 trigger, each checked directly:
10.0.29605.0, Cross-Cert10.29611.0.0, Endpoint Security10.0.29526.0).32.0.101.7085, dated 2026-03-03, untouched.Features enabledset logged on 07-25 and 07-26 is byte-identical.I have not identified what changed on the evening of 07-26, and I'd rather flag that honestly than guess. If your regression window assumes "shipped broken in 26.721.4979", this data point argues the binary alone isn't sufficient — something makes the GPU process take the Vulkan path where it previously didn't. Anyone else hitting this: checking whether your first CI 3033 predates or postdates your install of this build would help triangulate.
(Also still true from before: the package payload is byte-perfect against its own BlockMap, so
Modifiedremains a derived flag, not corruption.)---
Second correction + root of the variable repro: the loader is Dawn/WebGPU, not Chromium's Vulkan backend. Full workaround now verified against the actual trigger path.
Two things in my previous comment need fixing, and the fix explains why this reproduces for some users and not others.
1. The earlier workaround was incomplete (19 min, not durable)
--use-angle=d3d11 --disable-features=Vulkan,VulkanFromANGLE --disable-gpu-compositingsurvived 19 minutes of real use, then died to the samevk_swiftshader.dllblock. Sequence in the desktop log, every time:The identical two-line prelude (
mcp-app-sandbox attach→workspace-settings-webview Failed) precedes the earlier 07-26 21:24 kill as well. So the ICD is not only loaded at GPU-process startup — a webview opened later initializes it lazily.It's Dawn/WebGPU.
DawnWebGPUCacheandDawnGraphiteCacheboth had files written during the affected session.--disable-features=Vulkangates Chromium's Vulkan backend; Dawn does its own adapter enumeration and pulls in the SwiftShader Vulkan ICD as a fallback adapter, bypassing that switch.2. Complete workaround (verified against the real trigger)
Verification, with the failure path deliberately exercised:
Win32_Process.CommandLineof--type=gpu-process):use-angle=d3d11✓,disable-features=…Vulkan…✓,…WebGPU…✓ — so this is not a "flags silently dropped in the child" false positive.workspace-settings-webview Failedat 06:24:05, 06:24:58, 06:25:38 plusmcp-app-sandbox attach×3 and an IAB browser session. Previously that prelude killed the app within 13 seconds.Ok.Caveat: args-only, so Start-menu activation still dies; and disabling WebGPU may degrade any WebGPU-dependent UI.
3. Correcting myself: "the package version is not the variable" was a wrong inference
I reported that
26.721.4979.0ran cleanly for 1h54m on 07-25 and concluded the build wasn't the differentiator, with an unexplained change on 07-26. That inference was wrong. Counting the trigger in the desktop logs:| Date |
workspace-settings-webviewoccurrences | CI 3033 ||---|---|---|
| 07-13 … 07-24 (older builds) | 0 | 0 |
| 07-25 (this build, 1h54m clean session) | 0 | 0 |
| 07-26 | 10 | 1 |
| 07-27 | 34 | 4 |
The clean 07-25 session simply never opened that surface. Nothing environmental changed on 07-26. Also worth noting: the
workspace-settings-webviewcomponent does not appear anywhere in this machine's logs before 07-26, across all builds back to 07-13 — so on this box the trigger surface itself is new with26.721.41059.4. Why this repros for some users and not others (three conditions must coincide)
vk_swiftshader.dllat a signing level the AppX container rejects.vk_swiftshader.dllis never loaded and the CI block never fires.Condition 3 is the environment-dependent one and is probably why this is hard to reproduce internally: this machine is Intel Iris Xe integrated graphics, driver 32.0.101.7085 (2026-03-03). Boxes with discrete GPUs or newer drivers likely take the hardware path and never see it. Note this is not about user-side hardening — SAC, HVCI and DeviceGuard are all off here (previous comment); the container's signing-level enforcement is standard.
Implication for the fix: gating only Chromium's Vulkan backend will not be sufficient — Dawn's adapter enumeration reaches the ICD independently. Either ship the ICD at an acceptable signing level, drop it from the packaged build, or prevent Dawn from enumerating the SwiftShader fallback inside the container. Reproduction recipe if useful: run the packaged build on an integrated-GPU machine and open the workspace settings surface.
Retraction: my "condition 3" (only integrated-GPU machines are affected) is wrong — please disregard that repro recipe. The blast radius is wider.
In my previous comment I claimed the SwiftShader ICD is only loaded when Dawn falls back for lack of a hardware WebGPU adapter, and suggested reproducing on an integrated-GPU machine. The reporter's own hardware falsifies that: RTX 5090 Laptop (32.0.15.9201) + Intel Graphics (32.0.101.8331), both healthy — a machine with an unambiguously capable hardware WebGPU adapter — and it still hits the block.
Re-checking my own data, it contradicted me too and I missed it: during the affected 19-minute session on this machine,
GrShaderCachereceived new files and the GPU process was alive and healthy the whole time, i.e. hardware GPU rasterization was working — andvk_swiftshader.dllwas still loaded and blocked. So it was never a "no hardware → fall back" situation here either.Corrected mechanism: the ICD is loaded during adapter enumeration, not during fallback selection. Dawn enumerates available adapters — including the SwiftShader fallback adapter — to build the adapter list, and that enumeration
LoadLibrarys the ICD regardless of whether a hardware adapter exists or is ultimately chosen. Hardware capability provides no protection.Revised conditions for hitting this — now only two, and neither is hardware:
vk_swiftshader.dllat a signing level the AppX container rejects.So the practical blast radius is every user on an affected build who opens one of those surfaces, independent of GPU. That likely makes this higher-severity than my previous comment implied, and it means the internal repro does not need special hardware — just the packaged build plus opening the workspace-settings surface.
The rest of my earlier findings are unaffected: flags do propagate to the GPU process (verified via
Win32_Process.CommandLine); the full workaround--use-angle=d3d11 --disable-features=Vulkan,VulkanFromANGLE,WebGPU,WebGPUService,Dawn --disable-gpu-compositingheld through 3 deliberate triggerings of the failure path with 0 CI 3033 at T+10.8 min; and gating only Chromium's Vulkan backend is insufficient because Dawn enumerates independently.Apologies for the noise — flagging it explicitly because a hardware-specific repro recipe would have sent triage in the wrong direction.