[BUG] claude.exe triggers Windows BSOD via Wof.sys during directory listing (NtQueryDirectoryFileEx)

Status Open
Reported on v2.1.72
Maintainer reply None cached
Activity 41 comments · opened Mar 10, 2026

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?

claude.exe (Claude Code CLI) triggers a Windows kernel BSOD (Blue Screen of Death) by performing heavy NtQueryDirectoryFileEx syscalls (standard directory listing). The crash occurs in Wof.sys (Windows Overlay Filter) at WofPreDirectoryControlCallback+0x695 — a CFG (Control Flow Guard) indirect-call guard violation.

This is not an external Windows kernel bug in Wof.sys, but a Claude Code bug, due to Claude Code's intensive directory scanning, no delay in the same instant makes it a reliable trigger. Filing here so Anthropic is aware that Claude Code can crash Windows systems with this specific Wof.sys version, as well as wsl hypervisor.

Crash Statistics (all triggered by claude.exe)

| Date | BSODs | Bugcheck codes |
|------|-------|----------------|
| 2026-03-06 | 7 | 0x139, 0x3B, 0x50, 0x10E, 0x1E, 0x14F |
| 2026-03-09 | 1 | 0x139 |
| 2026-03-10 | 5 | 0x139 (x2), 0x3B (x2), 0x1E (x1) |
| 2026-03-11 | 1 | 0x50 |
| Total | 14 | 4 distinct types at same Wof.sys +0x695 offset |

All March 9-11 crashes have identical call stack:

NtQueryDirectoryFileEx → FLTMGR → Wof!WofPreDirectoryControlCallback+0x695 → CFG guard violation

4 manifestations of the same bug — the corrupted indirect call target lands in different memory regions:

  1. 0x139 — CFG guard catches invalid target before execution
  2. 0x3B (c0000005) — pointer escapes CFG, hits unmapped memory → access violation
  3. 0x1E (c0000005) — same access violation via different exception path
  4. 0x3B (c000001d) — pointer lands on non-code bytes → illegal instruction
  5. 0x50 — pointer references invalid page in nonpaged pool

Affected Configuration

  • Wof.sys: 10.0.26100.5074 (ships with Windows 11 25H2 build 26200)
  • Compact OS: Enabled increases crash frequency, but crashes also occur with CompactOS disabled
  • WOF minifilter: Attached at altitude 40700, intercepts every NTFS directory IRP

Microsoft Bug Report

Filed on Microsoft Q&A: https://learn.microsoft.com/en-us/answers/questions/5814272/wof-sys-bsod-0x139-kernel-security-check-failure-i

Potential Mitigation

Could Claude Code reduce the frequency/intensity of NtQueryDirectoryFileEx calls, or batch directory listings differently? This wouldn't fix the kernel bug, but might reduce the trigger rate on affected systems.

What Should Happen?

Claude Code should be able to perform directory listings without triggering a Windows BSOD. On systems with Wof.sys 10.0.26100.5074, the high volume of NtQueryDirectoryFileEx calls from claude.exe reliably crashes the kernel.

Ideally:

  1. Claude Code could throttle or batch directory enumeration on Windows to reduce the frequency of NtQueryDirectoryFileEx calls
  2. Or detect the vulnerable Wof.sys version and warn the user to disable Compact OS (compact /CompactOS:never)

Error Messages/Logs

WinDbg !analyze -v output (abbreviated):

KERNEL_SECURITY_CHECK_FAILURE (139)
  Arg1: 000000000000000a — indirect call guard check detected invalid control transfer
FAILURE_BUCKET_ID: 0x139_a_GUARD_ICALL_CHECK_FAILURE_Wof!WofPreDirectoryControlCallback+0x695
FAILURE_ID_HASH: {78ac0991-5393-0281-b23b-ce115373dc6d}

STACK_TEXT:
  nt!KeBugCheckEx
  nt!guard_icall_handler+0x1e
  nt!KscpCfgDispatchUserCallTargetEsSmep+0x11
  Ntfs!FindNextIndexEntry2+0x675
  Ntfs!NtfsContinueIndexEnumeration+0x10e
  Ntfs!NtfsQueryDirectory+0xd32
  FLTMGR!FltpLegacyProcessingAfterPreCallbacksCompleted+0x3fe
  FLTMGR!FltPerformSynchronousIo+0x443
  Wof!WofPreDirectoryControlCallback+0x695    <-- CRASH
  FLTMGR!FltpPerformPreCallbacksWorker+0x58f
  nt!NtQueryDirectoryFileEx+0xd8

PROCESS_NAME: claude.exe
MODULE_NAME: Wof
IMAGE_VERSION: 10.0.26100.5074

Second manifestation (0x3B at the same offset):
SYSTEM_SERVICE_EXCEPTION (3b)
  ExceptionCode: c0000005 (ACCESS_VIOLATION)
FAILURE_BUCKET_ID: AV_Wof!WofPreDirectoryControlCallback+0x695
FAILURE_ID_HASH: {3ae300a6-24ac-569b-3ce2-789a00065d56}

Steps to Reproduce

  1. Run Windows 11 25H2 (build 26200) with Wof.sys 10.0.26100.5074
  2. Optionally enable Compact OS: compact /CompactOS:always (increases frequency but not required)
  3. Run claude in a large directory (e.g., a monorepo with many files/subdirectories)
  4. Claude Code performs intensive directory listings via NtQueryDirectoryFileEx
  5. System BSODs with bugcheck 0x139 (KERNEL_SECURITY_CHECK_FAILURE) or 0x3B (SYSTEM_SERVICE_EXCEPTION)

Workaround: compact /CompactOS:never reduces frequency but does not eliminate the bug.

Environment:

  • Windows 11 25H2 Build 26200.7922
  • 192GB RAM, 32 cores, NVIDIA RTX 5000 Ada
  • 3.8 TB disk
  • Monorepo with ~100K files across nested directories

Claude Model

Opus

Is this a regression?

I don't know

Last Working Version

_No response_

Claude Code Version

2.1.72 (Claude Code)

Platform

Anthropic API

Operating System

Windows

Terminal/Shell

Windows Terminal

Additional Information

Minidumps & Diagnostics

Two ZIP archives with all kernel minidumps and diagnostic outputs:

  1. Original ZIP (Mar 9 dump) — 1x .dmp from 03-09
  2. New ZIP (Mar 10-11 dumps) — 5x .dmp files from 03-10 and 03-11

Contents: 6x .dmp files total, WinDbg analysis, system info, event logs, driver list, triage output.

Hardware Tests Performed (all clean)

  • Windows Memory Diagnostic: PASSED
  • Disk scan: No corruption
  • SFC /scannow: No integrity violations
  • DISM /RestoreHealth: Clean
  • In-place upgrade, repair install from ISO: Completed (replaced all files except Wof.sys)

Why This Is a Wof.sys Bug, Not Hardware

14 crashes at the exact same instruction (WofPreDirectoryControlCallback+0x695) across 6 days, producing 4 different exception types (0x139, 0x3B, 0x1E, 0x50) at the same offset. Random memory corruption wouldn't hit the same instruction deterministically. The 4 different bugcheck codes are expected — the corrupted indirect call target lands in different memory regions each time, producing different CPU exceptions.

Microsoft Q&A Thread

https://learn.microsoft.com/en-us/answers/questions/5814272/wof-sys-bsod-0x139-kernel-security-check-failure-i

View original on GitHub ↗

41 Comments

VRDate · 5 months ago

Related: #30137 reports the same BSODs (0x139, 0x1E, 0x50) on Windows 11 build 26200 — 5 BSODs in 2 days. Another user in that thread reports 15 BSODs in one day. Same root cause: Wof.sys CFG guard bug triggered by claude.exe directory enumeration.

VRDate · 5 months ago

Related Issues (for context)

Claude Code has a pattern of causing OS-level crashes across platforms. The Wof.sys BSOD is a separate kernel driver bug, but these show the broader stability picture:

Same Wof.sys BSOD (kernel-mode, fix owner: Microsoft):

  • #30137 — 5 BSODs in 2 days, another user reports 15 BSODs in one day. Same bugcheck codes (0x139, 0x1E, 0x50), same Windows build 26200.

Separate Bun/memory issues (user-mode, fix owner: Anthropic/Oven):

  • #21875 — 78 Bun segfaults, N-API race condition identified (Windows + WSL)
  • #27847 — Bun switch on corrupt value panics on Windows (Bun 1.3.10)
  • #18405 — Orphaned subagent processes accumulating 1GB+ RAM
  • #24960 — Kernel panic on macOS: 3 Claude processes hit 17.3GB on 18GB machine
  • #11315 — 129GB memory leak on Linux causing system freeze
  • oven-sh/bun#27471 — N-API vtable corruption causing hard reboots (5 in 8 days)

Important distinction: #30137 attributes BSODs to "Bun memory corruption propagating to kernel" — this is incorrect. User-mode memory corruption cannot cause a CFG guard failure (GUARD_ICALL_CHECK_FAILURE) in Wof.sys. CFG checks are compile-time integrity validations in the driver binary. The Wof.sys bug and the Bun memory bugs are two independent problems that Claude Code happens to trigger simultaneously through heavy directory enumeration and Node.js/Bun runtime usage respectively.

VRDate · 5 months ago

Update: 14 BSODs, 4th bugcheck type (0x50)

New crash — 2026-03-11 04:18 UTC:

| Bugcheck | Params | Dump |
|----------|--------|------|
| 0x00000050 PAGE_FAULT_IN_NONPAGED_AREA | 0xffffbb0e0760f040, 0x2, 0xfffff8040d352e58, 0x2 | 031126-30703-01.dmp |

Running total: 7 (Mar 6) + 1 (Mar 9) + 5 (Mar 10) + 1 (Mar 11) = 14 BSODs in 6 days.

4th bugcheck type: 0x50 joins 0x139, 0x3B, 0x1E. All are different manifestations of the same Wof.sys +0x695 indirect call corruption — the invalid pointer lands in different memory regions producing different exceptions:

  • 0x139 = CFG guard catches invalid target
  • 0x3B = access violation (unmapped) or illegal instruction (non-code)
  • 0x1E = kmode exception (access violation)
  • 0x50 = page fault in nonpaged area (NEW)

Wof.sys: Still 10.0.26100.1 — no Microsoft patch. CompactOS remains disabled. WOF minifilter still attached (cannot safely detach).

Trigger: claude.exe directory enumeration → NtQueryDirectoryFileEx → FLTMGR → Wof!WofPreDirectoryControlCallback+0x695.

Updated dump ZIP shared on MS Q&A #5814272.

VRDate · 5 months ago

Update: 16 BSODs — corruption spreading to other kernel modules

3 new BSODs today (2026-03-11), with a significant change: two of the three crashes are NO LONGER in Wof.sys.

| Time | Bugcheck | Faulting Module | WinDbg Bucket |
|------|----------|----------------|---------------|
| 04:18 | 0x50 PAGE_FAULT | Wof.sys +0x695 (same known bug) | AV_Wof!WofPreDirectoryControlCallback |
| 12:31 | 0x1E KMODE_EXCEPT | Ntfs.sys NtfsContinueIndexEnumeration+0x14 | AV_Ntfs!NtfsContinueIndexEnumeration |
| 12:52 | 0x3B SYS_SVC_EXCEPT | nllNetHub.sys (Norton) +0x876d | AV_nllNetHub!unknown_function |

Running total: 7 (Mar 6) + 1 (Mar 9) + 5 (Mar 10) + 3 (Mar 11) = 16 BSODs in 6 days.

Escalation: Kernel memory corruption spreading

Previously all 13 crashes blamed Wof.sys +0x695. Today, only 1 of 3 is Wof.sys — the other two are:

  1. Ntfs.sysNtfsContinueIndexEnumeration+0x14 is a push r15 instruction that caused a General Protection Fault. A #GP on push r15 means the stack pointer (RSP) was corrupted. This is still in the directory enumeration path (downstream from WOF's minifilter callback).
  1. nllNetHub.sys — Norton LifeLock network hub driver, in afwServ.exe (Norton Application Firewall). Unrelated to filesystem — suggests kernel pool corruption spreading beyond the directory enumeration path.

Theory: Wof.sys corruption at +0x695 is poisoning kernel pool/stack memory. When the corrupted pointer lands in WOF's own code, WinDbg blames Wof.sys. When it lands in NTFS or Norton memory, those modules crash instead. The Ntfs.sys crash (stack corruption in directory enumeration) strongly supports this — WOF's minifilter runs before NTFS in the filter chain, and could corrupt NTFS's stack frame.

System state

  • Wof.sys: 10.0.26100.1 (unchanged, no Microsoft patch)
  • CompactOS: OFF (disabled 2026-03-09)
  • WHEA: none (hardware errors clean)
  • Disk: 132GB free / 3.8TB
  • NVIDIA: 32.0.15.9571 (unchanged)

This is no longer just a WOF code defect — the corruption is destabilizing other kernel components. The system is becoming less stable over time, not more.

Related: #30137, MS Q&A #5814272

VRDate · 5 months ago

Control test: TreeSize Free scanned entire 3.8TB SSD — zero BSODs

To isolate whether the crash trigger is any directory enumeration or specifically Claude Code's parallel pattern, I ran TreeSize Free 4.8.1 as a control test:

  • Workload: Full-disk scan of 3.8TB SSD (every directory enumerated via NtQueryDirectoryFileEx through the same FLTMGR → Wof.sys minifilter chain)
  • Duration: ~5 minutes of heavy I/O (435 CPU seconds), 19+ minutes total monitoring
  • Result: Zero BSODs. Zero new minidumps. System completely stable.
  • Meanwhile: Claude Code triggered 3 BSODs in 8 hours today (0x50 Wof.sys, 0x1E Ntfs.sys, 0x3B nllNetHub.sys)

This proves:

  1. The hardware is not causing random memory corruption during disk I/O
  2. Wof.sys handles single-process sequential directory enumeration correctly
  3. The trigger is specific to Claude Code's pattern: dozens of concurrent ripgrep processes doing parallel directory walks simultaneously

The bug is a concurrency defect in Wof!WofPreDirectoryControlCallback — the callback's indirect call dispatch at +0x695 is not thread-safe under high-concurrency minifilter re-entrancy. Single-threaded callers (TreeSize, dir /s) never hit the race condition.

This also explains why "millions of Windows users" don't see this — most tools don't generate this level of concurrent directory enumeration through the minifilter stack.

VRDate · 5 months ago

Progress sync — all vendors now engaged

Actions taken today (2026-03-11)

Diagnostics:

  • WinDbg analyzed all 3 new dumps — crash is spreading: Wof.sys (1), Ntfs.sys (1), nllNetHub.sys/Norton (1)
  • TreeSize control test: full 3.8TB SSD scan, 30 min, zero BSODs — proves concurrency-specific trigger
  • MSI Center diagnostics inventory: HW Diagnosis, System Diagnosis, diskspd, pwrtest available
  • msinfo32 system report exported (2.1MB)
  • ACPI thermal zone: 85.1°C at idle — investigating (may be stale sensor)

Bug reports filed/updated across 4 platforms:

| Platform | ID | Owner | Status |
|----------|-----|-------|--------|
| GitHub (Anthropic) | #32870 | Software vendor | Open — no response yet |
| GitHub (Anthropic) | #30137 | Software vendor (3 users) | Open — no response yet |
| MS Q&A (Microsoft) | #5814272 | OS vendor | David-M (community) engaged, rebutted with evidence |
| MSI (HW vendor) | #1320187 | Hardware vendor | Filed today + msinfo32 attached |

Key evidence posted today:

  1. 3 different kernel modules crashing = escalating instability
  2. Ntfs.sys stack corruption (#GP on push r15) = WOF corrupting downstream modules
  3. TreeSize control test = hardware stable, concurrency-specific trigger confirmed
  4. BIOS E1822IWS.10E is latest — no MSI firmware fix available

Waiting on:

  • Anthropic: any acknowledgment or workaround (reduce concurrent ripgrep processes?)
  • Microsoft: Wof.sys patch (concurrency fix in WofPreDirectoryControlCallback)
  • MSI: BIOS/firmware investigation, thermal/memory controller assessment
VRDate · 5 months ago

Feedback Hub report filed

Microsoft's community advisor (David-M) confirmed this is a core driver defect and recommended filing via Feedback Hub for direct escalation to Microsoft engineers.

Feedback Hub link: https://aka.ms/AA106t77**

Please upvote if you're experiencing Wof.sys BSODs during Claude Code sessions. Higher engagement = higher priority for Microsoft's kernel team.

Current status: 17 BSODs in 7 days (2026-03-06 through 2026-03-12). Wof.sys 10.0.26100.1 still unpatched. CompactOS OFF, still crashing. 3 faulting kernel modules (Wof.sys, Ntfs.sys, Norton nllNetHub.sys).

VRDate · 5 months ago

BSOD #20 — 2026-03-14 00:19

Another crash overnight. Same identical bug:

Bugcheck: 0x139 KERNEL_SECURITY_CHECK_FAILURE
Bucket: 0x139_a_GUARD_ICALL_CHECK_FAILURE_Wof!WofPreDirectoryControlCallback
Hash: {78ac0991-5393-0281-b23b-ce115373dc6d}
Process: claude.exe

Stack:

claude.exe → NtQueryDirectoryFileEx → FLTMGR → Wof!WofPreDirectoryControlCallback+0x695
  → Ntfs!FindNextIndexEntry2+0x675 → KscpCfgDispatchUserCallTargetEsSmep+0x11
  → KiGeneralProtectionFault → guard_icall_handler → KeBugCheckEx

System state:

  • Wof.sys 10.0.26100.5074 — unchanged, no Microsoft patch
  • CompactOS OFF since 03-09
  • No WHEA hardware errors
  • System uptime before crash: 1 day 21 hours
  • Dump: 031426-31890-01.dmp (17MB)

Running total: 20 BSODs in 9 days (03-06 through 03-14). Same offset (+0x695), same process (claude.exe), same trigger (NtQueryDirectoryFileEx from concurrent ripgrep).

Still waiting for any acknowledgment or workaround suggestion from Anthropic. Even a simple "limit concurrent ripgrep processes" flag would help.

VRDate · 5 months ago

Workaround: Run Claude Code in WSL to avoid Wof.sys BSOD

Full writeup: https://gist.github.com/VRDate/862268b57dd197b8775f893a7be1e548

---

Claude Code BSOD Workaround — Wof.sys Crash on Windows 11 Build 26200+

Problem

Claude Code triggers BSOD (Blue Screen of Death) on Windows 11 Build 26200+ during normal operation. The crash occurs in Wof.sys (Windows Overlay Filter) when Claude's filesystem operations call NtQueryDirectoryFileEx, which passes through the WOF minifilter and hits a CFG (Control Flow Guard) violation.

Bugcheck codes: 0x139 (KERNEL_SECURITY_CHECK_FAILURE), 0x3B, 0x1E, 0x50

Faulting module: Wof.sys 10.0.26100.5074 at WofPreDirectoryControlCallback+0x695

Trigger: Any filesystem-heavy operation — directory listing, file search, glob patterns — the kind of thing Claude Code does constantly.

Bug reports:

Root Cause

This is a Windows kernel bug, not a Claude Code bug. Wof.sys (Windows Overlay Filter) handles WIM-backed files and CompactOS compression. When Claude Code (or any process) makes rapid NtQueryDirectoryFileEx calls on NTFS volumes, the WOF minifilter crashes in its directory control callback. CompactOS ON/OFF makes no difference — the bug is in the minifilter code path itself.

WOF is a critical Windows component — it cannot be disabled, detached, or unloaded without breaking Windows.

Workaround: Run Claude Code in WSL

Since the crash only happens on NTFS (Windows filesystem), running Claude Code inside WSL2 (which uses ext4) completely bypasses the Wof.sys code path.

Setup (5 minutes)

Prerequisites: WSL2 with Ubuntu (from Microsoft Store).

# 1. Install Ubuntu from MS Store (if not already)
wsl --install Ubuntu-24.04

# 2. Install Node.js inside WSL
wsl -d Ubuntu-24.04 -u root -- bash -c '
  curl -fsSL https://deb.nodesource.com/setup_22.x | bash -
  apt install -y nodejs
'

# 3. Install Claude Code inside WSL
wsl -d Ubuntu-24.04 -u root -- npm install -g @anthropic-ai/claude-code

# 4. Verify
wsl -d Ubuntu-24.04 -u root -- claude --version

Create the wrapper

Create claude.cmd in the same directory as claude.exe (typically %USERPROFILE%\.local\bin\):

@echo off
wsl -d Ubuntu-24.04 -u root -- claude %*

On Windows, .cmd takes priority over .exe in the same directory. Every claude invocation from cmd.exe, PowerShell, or Windows Terminal now goes through WSL automatically.

How it works

BEFORE (crashes):
  Windows cmd/terminal
    → claude.exe (Windows native)
      → NtQueryDirectoryFileEx on NTFS
        → Wof.sys minifilter → BSOD

AFTER (safe):
  Windows cmd/terminal
    → claude.cmd (wrapper)
      → wsl -- claude (runs in WSL)
        → ext4 filesystem (no Wof.sys)
        → /mnt/c/ for Windows files (read/write, no WOF callback)

Your project files stay on C:\ — Claude in WSL accesses them via /mnt/c/. Your IDE (VS Code, IntelliJ, etc.) runs on Windows watching the same files. No file duplication needed.

Reverting

When Microsoft patches Wof.sys, simply delete the wrapper:

del %USERPROFILE%\.local\bin\claude.cmd

Claude will fall back to claude.exe (Windows native).

What doesn't work

| Attempted fix | Result |
|---------------|--------|
| Disable CompactOS (compact /compactos:never) | Still crashes |
| Windows Update (KB5079473) | Did not update Wof.sys |
| Norton AV exclusions | Unrelated (separate nllNetHub.sys crash) |
| Disabling WOF service | DO NOT — breaks Windows |

Affected versions

  • Windows: Build 26200+ (Windows 11 24H2 Insider/Dev)
  • Wof.sys: 10.0.26100.5074 (unchanged across updates)
  • Claude Code: All versions (the bug is in the OS, not Claude)
  • Also affects: Any process making rapid filesystem directory queries (not Claude-specific)

Timeline

| Date | Event |
|------|-------|
| 2026-03-06 | First BSODs after Windows upgrade to Build 26200 |
| 2026-03-06 | 7 crashes in one day |
| 2026-03-12 | Feedback Hub report filed, GitHub issues opened |
| 2026-03-14 | WSL workaround deployed, 21 total crashes logged |
| TBD | Microsoft Wof.sys patch |

VRDate · 5 months ago

Update: Root cause proven + workaround tested (23 BSODs total)

What causes the crash

Claude Code fires multiple filesystem operations (reading files, searching directories) at the same time — especially when using sub-agents. On Windows 11 Build 26200+, the kernel driver Wof.sys cannot handle this many simultaneous directory queries and crashes with a Blue Screen.

It's not about how many files you have — it's about how many are read at the same time. One agent reading files one after another is fine. Two or more agents reading files simultaneously triggers the crash.

Proof from session logs

Extracted the exact tool calls from the JSONL transcript before each crash:

  • BSOD #22 (03-14 04:42) — 5 agents running in parallel via WSL, all reading files at the same time → kernel crash
  • BSOD #23 (03-14 05:32) — 2 sub-agents launched in the same response, both scanning 18 files concurrently → kernel crash
03:48:26  Claude finds 18 files matching *.jbang.kt
03:48:42  Sub-agent 1 starts reading all 18 files
03:49:51  Sub-agent 2 starts reading all 18 files (while #1 still running)
          ── both agents reading files at the same time ──
          ── 30-50 simultaneous filesystem calls ──
05:32:59  *** BLUE SCREEN — Wof.sys crash ***

Workaround: a "traffic light" for file operations

The fix is a tiny server that acts like a traffic light — it makes Claude's file operations wait in line instead of all running at once. Only one operation goes through at a time.

How it works:

  1. A small background server runs on your machine (port 9876)
  2. Before every file operation, Claude Code asks the server "can I go?"
  3. The server lets one operation through at a time, with a small delay between each
  4. This prevents the simultaneous burst that crashes Windows

Setup (2 minutes):

Install JBang (one-line install, runs on any Java), then:

# 1. Start the traffic light server in the background
jbang Mutex.jbang.kt &

# 2. Add this to ~/.claude/settings.json:
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash|Read|Glob|Grep|Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "bash mutex-acquire.sh"
          }
        ]
      }
    ]
  }
}

That's it. Claude Code will now wait in line for file operations instead of firing them all at once. If the server isn't running, Claude works normally (no impact on single-agent usage).

Speed: The default delay is 2 seconds between operations (safest). For faster interactive work, start with jbang Mutex.jbang.kt --interval 100 (100ms between operations — 10x faster, still safe in testing).

Test results

| Scenario | Tool calls | Result |
|----------|-----------|--------|
| 5 agents, no traffic light | ~36 concurrent reads | BSOD in minutes |
| 5 agents, with traffic light | 381 serialized calls | Stable, no crash |
| Normal tools (TreeSize, robocopy) | Sequential | Stable, no crash |

Files (all in the gist)

https://gist.github.com/VRDate/862268b57dd197b8775f893a7be1e548

| File | What it does |
|------|-------------|
| Mutex.jbang.kt | The traffic light server (~120 lines of Kotlin) |
| mutex-acquire.sh | The hook script that asks "can I go?" (6 lines of bash) |
| TestMutex.jbang.kt | Tests to verify the traffic light works correctly |
| gen-repro-data.sh | Script to reproduce the crash: generates test data + agent prompts |
| claude-bsod-workaround.md | Full documentation with setup instructions |

VRDate · 5 months ago

Minidump update — 23 BSODs, new ZIP with proof + mutex

New ZIP (4 dumps from 03-14 + root cause proof + mutex workaround):
https://drive.google.com/file/d/1bnn5LPNy_ygehdc2zy2QayZ0dyt-pKqc/view?usp=sharing

Contains: 4 minidumps, bsod-22-23-concurrent-proof.md (JSONL-extracted timeline proving concurrent agent I/O = crash), Mutex.jbang.kt (traffic light server), mutex-acquire.sh (hook), TestMutex.jbang.kt (tests), gen-repro-data.sh (1GB repro kit + 5 agent prompts).

Updated gist: https://gist.github.com/VRDate/862268b57dd197b8775f893a7be1e548

VRDate · 5 months ago

Update: 25 BSODs — root cause reframed

After 12 days and 25 BSODs, the root cause is clear: this is not a Wof.sys bug — it's Claude Code firing parallel filesystem tool calls with zero backpressure.

Proof: mutex daemon = stable, no mutex = crash

I built a rate-limiting daemon (the "traffic light" from my earlier post) that serializes filesystem tool calls with a configurable delay. Results:

| Period | Mutex daemon | BSODs |
|--------|-------------|-------|
| 03-14 to 03-16 (~3 days) | Running (v1, 100ms-2s interval) | 0 |
| 03-17 night | Offline (developing mutex v2 on sandbox port) | 2 within hours |

The moment the daemon was taken offline for development, BSODs returned. The production daemon wasn't running because I was testing a new version on a different port.

What happened on 03-17

Session was developing mutex daemon v2 (MCP protocol, team tracking, SSE events). All 118 tests passed. Then the model spawned an Explore sub-agent to search for Thymeleaf templates — 6 parallel filesystem operations in ~1 second:

  • 3 Glob calls (**/*.html, **/*.thymeleaf, **/gui/**)
  • 2 Grep calls (smartadmin in java + gradle files)
  • 1 Bash find command

All against a 200K-file monorepo. No throttle, no delay. BSOD within seconds: 0x3B SYSTEM_SERVICE_EXCEPTION in Wof!WofPreDirectoryControlCallback.

The real issue

No kernel minifilter is designed for the kind of burst concurrency Claude Code generates. The model decides to parallelize, the CLI executes immediately. A 15-100ms delay between filesystem tool calls would eliminate the problem entirely at negligible latency cost.

This should be built into Claude Code itself — not left as a user-created workaround. My mutex daemon proves the architecture works. The CLI needs the same thing natively.

Additional structural gap

Sub-agents spawned via the Agent tool run in their own process and do not inherit the parent's PreToolUse hooks. Even with the user-side mutex daemon running, sub-agent filesystem calls are completely unprotected. This is how BSOD #25 happened — the parent session had hooks, the sub-agent didn't.

Also relevant to @kolkov's deadlock report above

The same zero-backpressure parallel tool call pattern likely causes the system deadlock on Windows 10 (no BSOD, just freeze). Different symptom, same root cause: overwhelming the filesystem with concurrent operations.

Running total: 25 BSODs in 12 days. 18 confirmed Wof.sys. All from unthrottled concurrent NtQueryDirectoryFileEx calls.

Updated gist: https://gist.github.com/VRDate/862268b57dd197b8775f893a7be1e548

VRDate · 5 months ago

@bcherny @ant-kurt @fvolcic @ashwin-ant @bogini @chrislloyd @ThariqS @catherinewu @whyuan-cc @dhollman @rboyce-ant @dicksontsai @OctavianGuzu @hackyon-anthropic @wolffiex @igorkofman @sid374 @ddworken

Requesting attention — 25 BSODs in 12 days, zero Anthropic response on this issue or #30137. Multiple affected users including @kolkov (system deadlock on Win10).

This is not a Windows kernel bug. It is Claude Code firing parallel filesystem tool calls (Glob, Grep, Read, find) with zero backpressure. 6 concurrent operations in 1 second against a large codebase crashes any Windows machine. A 15-100ms delay between calls fixes it completely — I built a mutex daemon that proves this (3 days stable, 0 BSODs; removed it → 2 BSODs within hours).

The fix is simple: add a configurable rate limit to filesystem tool calls in the CLI. I've provided the full architecture, code, tests, and repro kit. This needs to be built into Claude Code natively.

Sub-agents spawned via the Agent tool also bypass PreToolUse hooks entirely — even the user-side workaround can't protect against that.

This issue has has repro, bug, and platform:windows labels but no assignee, no milestone, and the external label dismisses it as an OS problem. It isn't.

VRDate · 5 months ago

Fix submitted: PR #35710

A tool-mutex plugin has been developed and submitted as PR #35710 to fix this issue.

Root cause confirmed: Claude Code executes Glob/Grep/Read/Bash tools in parallel with no concurrency limit. Each triggers NtQueryDirectoryFileEx syscalls that overwhelm the Wof.sys kernel driver, causing BSOD.

Fix: File-based counting semaphore plugin that serializes filesystem tool calls:

  • Windows: max 1 concurrent op (prevents Wof.sys overload)
  • Linux/macOS: max 4 concurrent ops (prevents OOM)
  • 75ms cooldown between operations
  • PID-based stale slot cleanup

Verified: 256 concurrent workers — without mutex: 7/256 completed (16GB RSS, 249 timeouts). With mutex: 256/256 completed (290MB RSS, zero crashes).

27 BSODs logged on a 192GB/32-core workstation over 12 days before this fix was developed. 9 distinct bugcheck types (0x139, 0x3B, 0x1E, 0x50, 0x14F, 0x10E, 0x20001, 0xC2).

Cross-references:

VRDate · 5 months ago

@anthropics/claude-code-maintainers @anthropics/claude-code-reviewers @claude
@bcherny @ant-kurt @fvolcic @ashwin-ant @bogini @chrislloyd @ThariqS @catherinewu @whyuan-cc @dhollman @rboyce-ant @dicksontsai @OctavianGuzu @hackyon-anthropic @wolffiex @igorkofman @sid374 @ddworken
@OctavianGuzu @chrislloyd @ant-kurt — requesting a direct review from one of you. Still, no one is assigned to review https://github.com/anthropics/claude-code/pull/35710.

kolkov · 5 months ago

@VRDate Your PR and root cause analysis are excellent. For context — the parallel fs calls without backpressure you found is one of several architectural issues we've documented through reverse-engineering cli.js across 16 npm versions:

  1. No file locking on Read/Edit tools — concurrent agents overwrite each other's edits (#33949)
  2. Non-atomic JSONL writesinsertMessageChain() writes tool_use and tool_result one at a time in a for-loop, unchanged across 8 versions checked
  3. Streaming watchdog exists but disabledCLAUDE_ENABLE_STREAM_WATCHDOG hidden since v2.1.50, recently tuned to 45s/90s in v2.1.79 but still behind feature flag
  4. Bun/mimalloc crashes — 6 crashes in 4 days on Windows, 10-15 GB committed memory even in idle, process crashes taking down IDE (#36132)
  5. 21 threads per process — GDB analysis by @rstuart shows all Bun Pool threads deadlocked on a single futex (#26224)

Team response across all these: zero on streaming/crash issues for 8+ months. @catherinewu said "actively investigating" on Feb 23 — 30 days of silence since.

Your experience with the PR not being reviewed is unfortunately consistent.

Our issues: #33949 (root cause analysis) | #36132 (Bun memory crashes) | #35171 (auto-updater leak)
Related: #6836 (orphaned tool calls, 150+ reports) | #3648 (scroll bug, 👍694) | #26224 (streaming hangs, deadlock analysis by @rstuart)

VRDate · 5 months ago

@kolkov, My PR is a plugin I have been using for several days, and it is in the sweet spot between slowing down just 75ms and still letting the system work without crashing. I recommend installing it and reading the code at https://github.com/VRDate/claude-code/tree/claude/add-tool-mutex-Qytsn/plugins/tool-mutex. It uses a mutex to avoid excessive pressure on the OS, and it is just best practice for any CLI filesystem-intensive loads. Arguing that this bug is external is just not taking responsibility.

My Load Test Results (Linux, 4-core / 16 GB)

https://github.com/VRDate/claude-code/tree/claude/add-tool-mutex-Qytsn/plugins/tool-mutex/tests

Previous 256-worker stress test (with vs without mutex)

| Metric | No Mutex (256 workers) | With Mutex (256 workers) |
|---|---|---|
| Completed | 7/256 (2.7%) | 256/256 (100%) |
| Peak RSS | 16,272 MB | 290 MB |
| Min free memory | 35 MB (near OOM) | 15,857 MB |
| Crashes | YES (249 timeouts) | None |

At 1024 workers without mutex, Node.js is OOM-killed (exit code 137).

Node.js load test (16 workers)
Workers:          16
Ops completed:    16/16 (100%)
Peak RSS:         1,298 MB (main)
Free memory:      16,127 MB start → 14,858 MB min → 15,857 MB end
Crashes:          None
Total time:       25.2s
Python load test (16 workers, 160 total ops)
Workers:          16
Iterations:       10
Ops completed:    160/160 (100%)
Peak RSS:         17.6 MB
Free memory:      15,196 MB start → 14,671 MB min → 14,675 MB end
Crashes:          None
Total time:       25.0s

Show that Node.js is not the best way to create a CLI tool anyway.
@anthropics/claude-code-maintainers @anthropics/claude-code-reviewers @claude
@bcherny @ant-kurt @fvolcic @ashwin-ant @bogini @chrislloyd @ThariqS @catherinewu @whyuan-cc @dhollman @rboyce-ant @dicksontsai @OctavianGuzu @hackyon-anthropic @wolffiex @igorkofman @sid374 @ddworken
@OctavianGuzu @chrislloyd @ant-kurt — requesting a direct review from one of you. Still, no one is assigned to review https://github.com/anthropics/claude-code/pull/35710.

the0riginalgandalf · 4 months ago

Token bucket rate limiter — improved workaround for multi-session use

Building on @VRDate's excellent root cause analysis and PR #35710, we've published an improved workaround that fixes a failure mode we hit with the counting semaphore approach.

Repo: https://github.com/the0riginalgandalf/claude-wof-mitigation**

Why the semaphore approach can fail

We started with VRDate's semaphore (cpu_count // 2 concurrency + 75ms cooldown) and it worked on our laptop's low-power "office" mode — but BSODed on balanced mode with identical settings. The crash variable isn't concurrency count, it's syscall throughput rate. Faster CPUs (higher power plans, turbo boost) push more NtQueryDirectoryFileEx/sec through the Wof.sys callback at the same concurrency cap. Collision probability scales with the square of the rate.

Token bucket approach

A token bucket is the correct abstraction for rate limiting:

  • Capacity 4 — allows short responsive bursts for interactive use
  • Refill 10 tokens/sec — sustained ceiling well below the ~20-30/sec danger zone
  • Rate is CPU-independent — 10 ops/sec is 10 ops/sec regardless of clock speed

Secondary concurrency cap of 8 as belt-and-suspenders.

Multi-session optimization

We run 5-6 concurrent Claude Code sessions with subagents (/critique-plan, /deep-review workflows). Initial testing showed the original O_CREAT|O_EXCL file lock collapsed under contention — 3 sessions achieved only 1.4 ops/sec combined (86% wasted on lock contention). Three fixes:

  1. msvcrt.locking on Windows — OS kernel byte-range locks instead of create/delete file lock. Eliminates PermissionError convoy effect.
  2. Calculated sleep_try_consume_token returns the exact wait time until next refill. No blind 75ms polling.
  3. Random jitter (0-15ms) — breaks thundering herd across sessions.

Result: 6 sessions achieve 10.2 ops/sec combined (near-optimal ceiling saturation).

Stress test results

Tested on an Eluktronics laptop across all power modes with no BSODs:

| Test | Power Mode | Result |
|------|-----------|--------|
| 10 parallel tool calls | Office | Pass |
| 10 parallel tool calls | Balanced | Pass |
| 20 parallel tool calls | Balanced | Pass |
| 30 parallel tool calls | Beast (max performance) | Pass |
| 30s sustained (single session) | Balanced | 10.1 ops/sec |
| 20s sustained (6 concurrent sessions) | Balanced | 10.2 ops/sec combined |

Install

Copy hooks/ and mutex/ from the repo, add hooks to ~/.claude/settings.json. Full instructions in the README. Pure Python, no dependencies beyond stdlib (msvcrt on Windows, fcntl alternative on POSIX).

The repo also includes the full technical research document on the Wof.sys race condition.

the0riginalgandalf · 4 months ago

Update: Rate limiting alone doesn't work — Dev Drive (ReFS) is the real fix

Follow-up to my earlier comment. After 4 BSODs testing increasingly aggressive rate limiting, the conclusion is clear: userspace throttling cannot reliably prevent this crash under real multi-session workloads at high CPU performance levels. Dev Drive (ReFS) is the only reliable fix.

What we tried (and what failed)

| Attempt | Approach | Result |
|---------|----------|--------|
| 1 | Counting semaphore (VRDate's approach) | BSODed on balanced power mode |
| 2 | Token bucket at 10/sec | BSODed — ripgrep's 32-thread rayon pool amplified each Grep to ~320 Wof.sys syscalls/sec |
| 3 | Token bucket + tool weights + RAYON_NUM_THREADS=2 | BSODed within 11 min — 0x124 MCE (corruption cascading into hardware-level CPU exceptions) |
| 4 | Dev Drive (ReFS) | Stable — no BSODs under sustained heavy use |
| 4.5 | Dev Drive without rate limiting | BSODed — find.exe still hit NTFS system drive |
| 5 | Dev Drive + hooks for residual NTFS + fltmc detach | Stable under heavy multi-session beast mode |

The fix

This is a Microsoft kernel bug, not a Claude Code bug. Wof.sys has 8 prior CVEs including CVE-2023-21766 (same class — race condition UAF). The fix is to bypass Wof.sys entirely:

  1. Create a Dev Drive (ReFS) — Wof.sys doesn't attach to ReFS volumes
  2. Move project files there via junctionmklink /J so existing paths work transparently
  3. Move .claude config too — conversations, hooks, settings all do filesystem I/O
  4. Detach Wof from data drivesfltmc detach Wof D: for any non-system NTFS volumes
  5. Token bucket hooks for residual C: drive access (can't detach Wof from system drive)

Full setup instructions and the drive-aware hooks: https://github.com/the0riginalgandalf/claude-wof-mitigation

Why rate limiting fails at scale

The fundamental problem is amplification. Claude Code's Grep tool spawns rg.exe, which uses a rayon thread pool (default = CPU count). On a 32-core machine, one Grep call generates ~32 concurrent NtQueryDirectoryFileEx syscalls through Wof.sys. With multiple sessions running subagents doing Grep-heavy work, the effective syscall rate easily exceeds the crash threshold regardless of how aggressively you throttle tool starts.

Even with RAYON_NUM_THREADS=1 + 4 tokens/sec + tool weights, we still BSODed because other tools (find.exe, system PATH resolution) hit NTFS volumes outside the project directory.

For Anthropic

The right long-term fix is for Microsoft to patch Wof.sys. In the meantime, consider documenting Dev Drive as a recommended setup for Windows Claude Code users — especially those running multiple concurrent sessions. It's ironic that Microsoft's own Dev Drive product is the workaround for Microsoft's own kernel bug.

VRDate · 4 months ago

@the0riginalgandalf @thompa2 Your approach of bypassing Wof.sys by relocating to a separate partition or external drive with different filesystem settings is genuinely clever. To make it practical for more users though, the solution should be proportional to available resources — CPU, storage, and partition layout — and fully automatic. Using robocopy to mirror Claude's working directory (including all subfolders and the project root) with a scheduled sync-back would eliminate the manual overhead entirely.

Worth clarifying the scope too: while this looks like a Windows-only edge case on the surface, it's actually OS-agnostic. The WSL BSODs under Ubuntu confirm the same underlying contention pattern — the watchdog that should be throttling concurrent filesystem syscalls simply isn't doing its job, regardless of the layer.

Since we can't wait on a fix from upstream while maintainers are buried in other issues, a plugin that replaces the missing watchdog behavior is the right path forward. I'll fork your extended solution and iterate on it.

Solid contribution — this is real progress from a fresh attack vector. Thanks for the time and effort.

the0riginalgandalf · 4 months ago

@VRDate FYI I opened a vulnerability report with Microsoft about this issue. Case is listed as under review. Will update if I hear anything useful back.

TheSmallKiwi · 4 months ago

@VRDate @the0riginalgandalf Thankyou both for your work on this. Based on the Dev drive recommendation I did a fresh windows install after repartitioning and set up a Dev drive and set up the hooks from https://github.com/the0riginalgandalf/claude-wof-mitigation & So far, so good. No instability! Down from several BSODs a day.

the0riginalgandalf · 4 months ago

@TheSmallKiwi glad that worked for you! Hopefully you don't run into the next problem I did. Had another BSOD today, but not directly related to this issue.

Turns out 13th/14th Gen Raptor Lake desktop and laptop CPUs have a known "Vmin Shift Instability," which causes high voltage requests, crashes, and permanent, accelerated, damage-induced degradation. Need to update the microcode to prevent further damage.

What's less clear is the connection between this issue and the wof.sys issue. Did some digging and found my system was throwing WHEA errors on the Wof.sys BSOD dates:

  • Apr 3: 1 parity error (APIC 17)
  • Apr 4: 4 errors — 2 parity (APIC 17), 2 TLB + 1 unclassified (APIC 25)

These were the exact same days I had 4 Wof.sys BSODs. The CPU was actively throwing corrected errors while Wof.sys was handling filesystem callbacks. So my guess is there's a link there. It would be notable if both you and @VRDate were also experiencing this issue and had 13/14th gen Raptor Lake Intel CPUs with the bad microcode (0x123). Updating to 0x129 or later should fix the bad voltage handling, but won't undo any damage that has occurred.

TheSmallKiwi · 4 months ago

I have a 13900HX (laptop) which Intel claims was unaffected by the killer microcode. Nonetheless I kept the BIOS as up-to-date as I could so I hope I've avoided permanent damage, but who knows?

rzinnatullin · 1 month ago

Same issue on my laptop (MSI Katana 17 HX B14W with i9-14900HX). The issue started happening yesterday. 10 BSODs already.

Andre-Erasmus · 1 month ago

Confirming repro on another i9-14900HX laptop, + an in-place Dev Drive migration recipe with a Claude-specific gotcha not yet mentioned in this thread

Machine: ASUS ROG Strix G16 G614JVR (i9-14900HX), Windows 11 Home build 26200, single NVMe, CompactOS disabled, Wof attached to C: (NTFS).

Crash series:0x139 KERNEL_SECURITY_CHECK_FAILURE (Arg1=0xa) between 16–18 Jul 2026. Six minidumps analysed — all the identical bucket reported above: GUARD_ICALL_CHECK_FAILURE_Wof!WofPreDirectoryControlCallback (+0x695), kCFG GP fault under Ntfs!FindNextIndexEntry2, faulting process = whichever was enumerating at the time (python scripts, robocopy). Onset on our box was ~5h after KB5101650 serviced ntfs.sys + Wof.sys to 10.0.26100.8875.

Data points that may help triage:

  1. Hardware eliminated mid-series. Since 14900HX / Vmin-shift came up in this thread: we flashed BIOS G614JVR.322 (microcode 0x12B) mid-series — WHEA-clean and chkdsk-clean since — and the 0x139s continued identically (two more post-flash). On our machine the Wof issue and the Raptor Lake degradation issue are clearly separate axes.
  2. Not specific to claude.exe. One crash hit ~90 seconds into a first-ever OpenAI Codex CLI session (its bundled multi-threaded ripgrep scanning config dirs), stacked with a cloud-sync client rescan. Any agent-style concurrent enumerator reproduces this.
  3. Background sync clients are silent co-triggers. Google Drive for desktop "computer backup" pointed at the ~/.claude folder is a standing concurrent enumerator — it rescans ~100K files on every restart and on "Reset local data". Worth checking what's watching your agent dirs before attributing the crash to the foreground tool alone.
  4. Cross-process serialization hooks + RAYON_NUM_THREADS=2 (set at user scope so every rg-based tool inherits it, not just Claude sessions) reduced frequency but did not eliminate crashes — consistent with @the0riginalgandalf's conclusion that userspace throttling alone isn't sufficient.

In-place Dev Drive migration recipe (no repartition, no fresh install): create an expandable VHDX on C: (C:\DevDrive\claude.vhdx) → attach → partition → format /DevDrv → assign V: → robocopy the workspace across (single-threaded, with nothing else enumerating — one of our 8 crashes was robocopy racing a leftover scanner mid-migration) → Rename-Item C:\Claude C:\Claude-oldmklink /J C:\Claude V:\Claude. Every existing absolute path keeps working, and Wof never sees workspace enumeration again. Windows re-attaches the VHDX at boot natively (verified across both clean and crash reboots — no scheduled task needed).

⚠ Gotcha for anyone applying the junction variant: Claude Code keys per-project history/memory by the resolved realpath. After the junction migration, every project-state folder key under ~/.claude/projects/ changes (C--Claude-...V--Claude-...): --continue/--resume suddenly find nothing, and anything that hardcodes the old encoded key fails silently (we found 39 scripts/hooks doing so, all guarded by fail-open .exists() checks — zero error messages). Fix: rename the old key folders to the new encoding, then grep your tooling for the old encoded string. A fresh install avoids this entirely; an in-place migration hits it every time.

Since the migration, workspace enumeration no longer touches Wof; residual exposure is only the remaining NTFS surfaces (sync clients, other tools' config dirs on C:). Happy to share dump details if useful for the Microsoft case.

rzinnatullin · 1 month ago

I confirm that in my case BSODs started after installing KB5101650 Windows Update. The update was installed on 2026-07-16 since when BSODs started. Today (2026-07-18) I uninstalled the update, BSODs stopped immediately.
For reference, wof.sys version was 6.2.26100.8875 (buggy), after uninstalling the update the wof.sys version was reverted to 6.2.26100.8521.
The wof.sys bug may be somehow related to i9-14900HX processor, because on my other laptop with i7-12700H the same updated wof.sys works with no issues with Claude, however, tasks performed by Claude were not exactly the same.

KZelab · 1 month ago

Just started getting this on my Alienware m18 R2 laptop (I9-14900HX)

JohannOosthuizen · 1 month ago

Confirming this on a second, unrelated machine four months later — same FAILURE_ID_HASH, same Wof!WofPreDirectoryControlCallback+0x695 offset — but on Wof.sys 10.0.26100.8875 / build 26200.8894 rather than the 10.0.26100.5074 / 26200.7922 in the original report. The defect survived at least one servicing cycle, so "wait for a Windows update" is not currently a viable mitigation. Two further data points below: a non-Claude-Code enumerator hitting the same path, and a quantified measure of how much the Compact OS workaround actually buys.

---

Environment

| | This report | Original issue |
|---|---|---|
| OS build | Windows 11 25H2 26200.8894 | 26200.7922 |
| Wof.sys | 10.0.26100.8875 | 10.0.26100.5074 |
| ntoskrnl.exe | 10.0.26100.8894 | — |
| CPU | Intel Core i9-14900HX (laptop) | 32-core workstation |
| Volume | Single NTFS, ~3.8 TB, ~92 GB free | 3.8 TB |
| Compact OS | Enabled at onset, later disabled | Enabled |

Hyper-V root enlightenment active. Wof.sys is attached as a boot-start minifilter at altitude 40700, same as reported. Ntfs.sys and Wof.sys are both dated 2026-07-14 (July cumulative update).

Crash signature — identical

Two buckets observed across seven crashes (six minidumps retained):

FAILURE_BUCKET_ID: 0x139_a_GUARD_ICALL_CHECK_FAILURE_Wof!WofPreDirectoryControlCallback
FAILURE_ID_HASH:   {78ac0991-5393-0281-b23b-ce115373dc6d}

FAILURE_BUCKET_ID: AV_Wof!WofPreDirectoryControlCallback
FAILURE_ID_HASH:   {3ae300a6-24ac-569b-3ce2-789a00065d56}

Both hashes match this issue exactly. Both resolve to SYMBOL_NAME: Wof!WofPreDirectoryControlCallback+695 — the same +0x695 offset. Six 0x139 and one 0x3B.

<details>
<summary>Trap frame (0x139)</summary>

Arg1: 000000000000000a, Indirect call guard check detected invalid control transfer

nt!KscpCfgDispatchUserCallTargetEsSmep+0x11:
fffff800`a9dc0791 4f8b1cd3  mov r11,qword ptr [r11+r10*8] ds:fbffe9ce`f691f4a0=????????????????

r11=fbffe9cef691f4a0

A prior crash showed r11=fbffff64b5ac4458. Both targets are non-canonical, and both carry a 0xfb high byte where a valid kernel pointer would have 0xff — i.e. the same single-byte-off pattern in the high half of the pointer, not arbitrary garbage.
</details>

<details>
<summary>Full stack (0x139) — matches the issue with the intermediate FLTMGR frames filled in</summary>

nt!KeBugCheckEx
nt!guard_icall_handler+0x1e
nt!RtlpExecuteHandlerForException+0xf
nt!RtlDispatchException+0x2d2
nt!KiDispatchException+0x35f
nt!KiExceptionDispatch+0x145
nt!KiGeneralProtectionFault+0x365
nt!KscpCfgDispatchUserCallTargetEsSmep+0x11
Ntfs!FindNextIndexEntry2+0x675
Ntfs!NtfsContinueIndexEnumeration+0x10e
Ntfs!NtfsQueryDirectory+0xd32
Ntfs!NtfsCommonDirectoryControl+0x2ce
Ntfs!NtfsFsdDirectoryControl+0xcb
nt!IopfCallDriver+0x5b
nt!IofCallDriver+0x13
FLTMGR!FltpLegacyProcessingAfterPreCallbacksCompleted+0x3fe
FLTMGR!FltPerformSynchronousIo+0x443
Wof!WofPreDirectoryControlCallback+0x695
FLTMGR!FltpPerformPreCallbacksWorker+0x568
FLTMGR!FltpPassThroughInternal+0xc0
FLTMGR!FltpPassThrough+0x230
FLTMGR!FltpDispatch+0x228
nt!IopfCallDriver+0x5b
nt!IofCallDriver+0x13
nt!IopSynchronousServiceTail+0x1c5
nt!NtQueryDirectoryFileEx+0xd8
nt!KiSystemServiceCopyEnd+0x25

</details>

<details>
<summary>0x3B variant</summary>

Identical stack from Wof!WofPreDirectoryControlCallback+0x695 downward. ExceptionCode c0000005; rip lands at Ntfs!NtfsContinueIndexEnumeration+0 with rbp=4080000040000003. This is the same "pointer escapes CFG and is executed" manifestation described in the issue's four-manifestations section, just reached from a slightly different frame.
</details>

---

New data point 1 — the defect survived a servicing cycle

The original report is against Wof.sys 10.0.26100.5074 on build 26200.7922 (March 2026). This system is on Wof.sys 10.0.26100.8875, build 26200.8894 (July 2026) — several driver revisions later. Same symbol, same +0x695, same two failure hashes.

Observed fact: the bug is present on both driver builds. Practical consequence for the issue's "Proposed Mitigations" section: detecting a "vulnerable Wof.sys version" cannot currently be done by pinning a single known-bad version — both the March and July drivers reproduce it.

New data point 2 — a second, non-Claude-Code enumerator reaches the same defect

This is the part most relevant to PR #35710's scope.

On the two most recent crashes the faulting process is dartvm.exe — the Dart/Flutter MCP language server, which runs a persistent recursive filesystem watcher. This machine was running Claude Code and the Dart MCP server concurrently against a Flutter project.

| Time | Bugcheck | Faulting process | Uptime |
|---|---|---|---|
| 11:15:40 | 0x139 | — | 0:25 |
| 11:41:26 | 0x139 | — | 0:10 |
| 11:53:01 | 0x139 | SystemSettings | 0:10:34 |
| 13:34:51 | 0x139 | dartvm.exe | 1:41 |
| 16:19:32 | 0x3B (0xc0000005) | dartvm.exe | 2:43:51 |

Note also the 11:53 crash attributed to SystemSettings — an ordinary shell process doing a directory listing was enough to be the one holding the IRP when the driver faulted.

Observed fact: the crashing thread is not always Claude Code's. Reading (inference): the defect is in the shared Wof.sys directory-control path and is reachable by any sufficiently concurrent directory-enumeration workload on the volume. The process named in the dump is whichever caller happened to be inside NtQueryDirectoryFileEx at the moment, not necessarily the one that created the concurrency.

New data point 3 — quantified effect of the Compact OS workaround

compact /CompactOs:never was applied mid-day, between the 11:53 and 13:34 crashes.

| | Mean time between failures |
|---|---|
| Before | ~10–25 min |
| After | ~101 min, then ~164 min |

Mean uptime went from ~17.5 min to ~132.5 min — roughly a 7.6x improvement — but crashes continued. Small sample: two observations either side. This confirms the issue's characterization of the workaround as partial and puts a number on it. Mechanically (inference): decompressing OS binaries removes most of Wof's decompression work, but it does not detach the minifilter from the directory-control path, so the faulting callback still runs on every directory enumeration.

---

Onset correlation — flagged as inference, not proof

Sequence on this machine:

  • 2026-07-09 — Flutter/Dart SDK installed; Dart MCP server added to the workflow shortly after, used alongside Claude Code
  • 2026-07-14 — July cumulative update replaced Wof.sys and Ntfs.sys
  • 2026-07-16 — first 0x139
  • 2026-07-20, 2026-07-21 — remaining six crashes

No 0x139 bugchecks appear anywhere in ~3 months of retained event logs prior to 2026-07-16.

The 2026-07-14 driver replacement initially looked causal because it lands two days before the first crash. I do not think it is: the same defect is documented in this issue against a March 2026 driver, so the July update is most likely coincidental. The more probable reading is that the change on this machine was the introduction of a second concurrent enumerating tool, which pushed a pre-existing latent defect above its trigger threshold. Stated explicitly as inference — I cannot separate the two changes from the evidence I have.

Ruled out

  • Filesystem corruption — NTFS event ID 98 reports all volumes healthy.
  • kCFG false positive — the indirect call targets are genuinely non-canonical (0xfb high byte), so CFG is catching a real bad transfer, not misfiring.
  • Hardware — deterministic failure at an identical instruction offset across all seven crashes, on different silicon from the original report (mobile i9-14900HX vs. the original 32-core workstation).

---

Open question for maintainers

PR #35710's semaphore covers Claude Code's own Glob / Grep / Read / Bash invocations. Based on the evidence above, the concurrency that trips this defect is volume-wide, not process-wide: a file-watching MCP language server enumerating in its own process is outside that semaphore and was the faulting process on two of the seven crashes here.

Is the tool-mutex approach intended to be scoped only to Claude Code's in-process filesystem tools, or is there a path to covering the MCP-server case — e.g. a machine-wide rather than session-wide semaphore, or guidance that the mutex alone is insufficient when other file-watching tooling runs alongside Claude Code? A fix scoped to Claude Code's own tools would have reduced but, on this machine, probably not eliminated the crashes.

Happy to provide additional !analyze -v output or dump detail if useful.

JohannOosthuizen · 1 month ago

Workaround: serializing filesystem tool calls with hooks (no code changes, installable today)

Following up on my earlier data — since PR #35710's tool mutex isn't merged, I built the same idea out of the existing hooks system: a PreToolUse/PostToolUse pair that serializes all of Claude Code's filesystem tool calls through a mkdir-based lock. Posting it here since it's working on the machine described above and others hitting this can install it today.

Result so far: the machine went from nine Wof.sys bugchecks in three days (seven of them in one afternoon, longest-ever uptime 2 h 43 m) to 21+ hours crash-free with the hook active during normal Claude Code + MCP-server workloads. Single machine, single day — treat it as a strong signal, not proof.

How it works

Three hook registrations in settings.json:

| Event | Matcher | Action |
|---|---|---|
| PreToolUse | Bash\|Read\|Glob\|Grep\|Edit\|Write | acquire lock (blocking, bounded) |
| PostToolUse | same | release |
| PostToolUseFailure | same | release |

The PostToolUseFailure registration matters: Claude Code fires a separate event when a tool call fails, so without it one failed call strands the lock.

Design properties, all deliberate:

  • mkdir as the atomic primitive — atomic on NTFS, no race between test and create, no dependencies.
  • Fails open, never hangs. A contended acquire polls at 100 ms; after 20 s it gives up and lets the call proceed unserialized. Worst case you lose the protection for one call — you never lose the session.
  • Stale-lock reclamation. A lock older than 15 s is treated as abandoned (holder crashed mid-call) and reclaimed. Since the lock is only held for the duration of one tool call's dispatch, a legitimately held lock is almost always younger than that.
  • Machine-wide across Claude Code sessions. The lock lives at $HOME/.claude/wof-mutex.lock, so concurrent sessions/subagents on the same machine serialize against each other too — which is what you want, since the Wof.sys race is volume-wide.

Install

~/.claude/wof-mutex-acquire.sh:

#!/bin/sh
# Serialize Claude Code filesystem tool calls.
#
# Works around a race in the Windows Overlay Filter (Wof.sys) that bugchecks the
# machine during concurrent NTFS directory enumeration:
#   Wof!WofPreDirectoryControlCallback+0x695
#   https://github.com/anthropics/claude-code/issues/32870
#
# Uses mkdir as the atomic primitive. Fails OPEN, never blocks indefinitely:
# after MAXWAIT the call proceeds unserialized rather than hanging the session.

LOCK="$HOME/.claude/wof-mutex.lock"
STALE=15    # seconds before a held lock is treated as abandoned
MAXWAIT=20  # seconds to wait before giving up and proceeding anyway

i=0
limit=$((MAXWAIT * 10))

while [ "$i" -lt "$limit" ]; do
  if mkdir "$LOCK" 2>/dev/null; then
    exit 0
  fi

  # Reclaim a lock whose holder died before releasing it.
  held=$(stat -c %Y "$LOCK" 2>/dev/null)
  if [ -n "$held" ]; then
    now=$(date +%s)
    if [ $((now - held)) -gt "$STALE" ]; then
      rmdir "$LOCK" 2>/dev/null
    fi
  fi

  sleep 0.1
  i=$((i + 1))
done

exit 0

~/.claude/wof-mutex-release.sh:

#!/bin/sh
# Release the lock taken by wof-mutex-acquire.sh.
# Registered on both PostToolUse and PostToolUseFailure so a failing tool does
# not strand the lock. rmdir on an absent directory is a harmless no-op.

rmdir "$HOME/.claude/wof-mutex.lock" 2>/dev/null
exit 0

Merge into ~/.claude/settings.json (alongside your existing keys):

"hooks": {
  "PreToolUse": [
    {
      "matcher": "Bash|Read|Glob|Grep|Edit|Write",
      "hooks": [
        {
          "type": "command",
          "command": "sh \"$HOME/.claude/wof-mutex-acquire.sh\"",
          "shell": "bash",
          "timeout": 30,
          "statusMessage": "Serializing filesystem access (Wof.sys workaround)"
        }
      ]
    }
  ],
  "PostToolUse": [
    {
      "matcher": "Bash|Read|Glob|Grep|Edit|Write",
      "hooks": [
        {
          "type": "command",
          "command": "sh \"$HOME/.claude/wof-mutex-release.sh\"",
          "shell": "bash",
          "timeout": 10
        }
      ]
    }
  ],
  "PostToolUseFailure": [
    {
      "matcher": "Bash|Read|Glob|Grep|Edit|Write",
      "hooks": [
        {
          "type": "command",
          "command": "sh \"$HOME/.claude/wof-mutex-release.sh\"",
          "shell": "bash",
          "timeout": 10
        }
      ]
    }
  ]
}

Notes:

  • "shell": "bash" runs the scripts under Git Bash, which ships with Git for Windows (a Claude Code prerequisite on Windows). stat -c %Y is GNU-stat syntax — fine there. The bug is Windows-only, so no portability effort was made.
  • No jq or other dependencies — plain POSIX sh plus GNU stat.
  • Claude Code's settings watcher picks the hooks up live; no restart needed (verified with a sentinel write from inside the hook).

Performance impact — measured

This is not free. Numbers from the machine above (i9-14900HX, NVMe):

| Scenario | Cost |
|---|---|
| Uncontended call (warm) | ~118 ms added per filesystem tool call (acquire + release pair, mean of 5 runs) |
| First call after install (cold) | ~448 ms (shell spawn + page-in; one-time) |
| Contended call | waits for the in-flight call to finish, polling at 100 ms |
| Pathological (holder hung) | hard cap 20 s, then proceeds unserialized (fail-open) |

How that ~118 ms lands in practice:

  • Almost all of it is process spawn overhead — two sh launches per tool call — not lock contention. It's a flat per-call tax.
  • Long calls barely notice (a 30 s build in Bash pays 0.4%); rapid-fire small calls notice most (a 50 ms Read roughly triples in wall-clock).
  • Parallel tool batches become sequential. This is the mechanism, not a side effect — concurrent directory enumeration is exactly what trips the driver — but it means a turn that would have run 5 tool calls concurrently now runs them back-to-back. For I/O-heavy fan-outs, wall-clock goes from max(calls) to sum(calls).
  • Subjectively: sessions feel slightly slower on bursts of small file operations, unchanged on anything compute- or build-bound. A day of heavy use has been entirely workable.

If the tax bothers you, the matcher can be narrowed to Glob|Grep|Bash — the directory-enumerating tools — leaving Read/Edit/Write (single-file operations) at full speed. I haven't tested whether the narrow matcher still suppresses the crashes, so I'm running the broad one until I have more uptime data. Single-file ops appearing in crash-time concurrency can't be ruled out from my dumps.

What this does not protect against

Being explicit, because this is a mitigation, not a fix:

  1. Threads inside a single tool call. One Grep invocation runs ripgrep, which walks directories multi-threaded internally. The hook serializes calls, not the parallelism within one.
  2. Non-Claude-Code enumerators. MCP language servers with their own file watchers (my crashes named the Dart VM's process), indexers, backup agents — all outside the hook. This is the volume-wide-concurrency point from my previous comment: a Claude-Code-side mutex reduces the trigger surface, it cannot eliminate it.
  3. The driver is still broken. This buys stability while Microsoft fixes Wof.sys; it's not a reason to close the issue.

Given (1) and (2), I'd have predicted a reduction rather than the clean 21 h I'm seeing — possibly the removed concurrency drops total trigger pressure below threshold even though other enumerators remain. More uptime data will tell.

Happy to report back with longer-term numbers or the narrow-matcher experiment.

lexliller · 1 month ago

Adding another independent machine with the identical failure bucket, on a newer Wof.sys than previously reported (10.0.26100.8875 vs 10.0.26100.5074) — so the July 2026 cumulative (KB5101650) restamped the binary without fixing the bug.

Machine: Alienware m18 R2, Windows 11 24H2 build 26100.8894, Wof.sys 10.0.26100.8875
Crashes: 5 between 2026-07-16 and 2026-07-25, all the same bucket. Crashing process was python.exe in earlier dumps and claude.exe in the latest (2026-07-25), both doing directory enumeration.

!analyze -v from the 2026-07-25 minidump:

KERNEL_SECURITY_CHECK_FAILURE (139)
Arg1: 000000000000000a, Indirect call guard check detected invalid control transfer.

PROCESS_NAME:  claude.exe
IMAGE_NAME:  Wof.sys
IMAGE_VERSION:  10.0.26100.8875
FAILURE_BUCKET_ID:  0x139_a_GUARD_ICALL_CHECK_FAILURE_Wof!WofPreDirectoryControlCallback
BUCKET_ID_FUNC_OFFSET:  695

STACK_TEXT (trimmed):
nt!KiGeneralProtectionFault+0x365
nt!KscpCfgDispatchUserCallTargetEsSmep+0x11
Ntfs!FindNextIndexEntry2+0x675
Ntfs!NtfsContinueIndexEnumeration+0x10e
Ntfs!NtfsQueryDirectory+0xd32
Ntfs!NtfsCommonDirectoryControl+0x2ce
Ntfs!NtfsFsdDirectoryControl+0xcb
FLTMGR!FltPerformSynchronousIo+0x443
Wof!WofPreDirectoryControlCallback+0x695
FLTMGR!FltpPerformPreCallbacksWorker+0x568
nt!NtQueryDirectoryFileEx+0xd8

The faulting CFG dispatch dereferences a non-canonical fbff.... address in r11 (fbff8b8fec5fe370 in this dump, fbffa6be65bac5a0 in the 7/23 one — same corruption shape, different values, different processes), consistent with a garbage callback target fed into the CFG bitmap computation rather than random hardware corruption.

Corroborating observations matching this thread:

  • Identical instruction offset (+0x695) across all 5 crashes and across processes.
  • Crashes correlate with concurrent directory-walking workloads (Claude Code sessions); no thermal/WHEA events, NTFS and NVMe healthy, SFC/DISM clean.
  • CompactOS is off on this machine (compact /compactos:query → "not in the Compact state"), so the bug does not require CompactOS — WOF's pre-directory-control callback fires regardless.
  • Not fixed as of build 26100.8894 / Wof.sys 10.0.26100.8875 (July 2026 patch level).
dxdum · 1 month ago

Independent reproduction on different hardware, plus the concrete corrupted field in NTFS

Hit this twice today on a different machine than the original report. Signature matches byte for byte. Adding the piece that I could not find in this thread or in the MS Q&A: the exact NTFS structure field that gets clobbered, which pins down the Wof -> NTFS corruption path rather than inferring it.

System

| Item | Value |
|---|---|
| OS | Windows 11 25H2, build 26200.8875 (July 2026 CU) |
| Kernel / Ntfs.sys | 10.0.26100.8875 |
| Wof.sys | shipped 2026-07-14 with the July CU, still vulnerable |
| Hardware | MSI Titan 18 HX A14VHG, i9-14900HX, 128 GB RAM, single 1.9 TB NTFS volume |
| Compact OS | already disabled ("system is not in the Compact state") |
| Defender real-time | disabled |
| WOF filter | loaded, BOOT_START, altitude 40700, 4 instances, attached to C: |

Two bugchecks 40 minutes apart, both 0x139 arg1=0xa (GUARD_ICALL_CHECK_FAILURE), both Ntfs!FindNextIndexEntry2+0x675, in two different processes enumerating two different directories:

crash 1  python.exe  NtQueryDirectoryFileEx  ->  \python\Lib
crash 2  pwsh.exe    NtQueryDirectoryFile    ->  <redacted>\.claude\projects\<redacted>\tool-results

Different directories, same volume, same code path. That rules out on-disk index corruption in one directory (chkdsk is a dead end here) and points at corrupted in-memory volume state.

Root cause, concretely

NTFS selects its name comparison routine through an index into a function pointer table inside the Ntfs.sys image:

Ntfs!FindNextIndexEntry2+0x13f:
    mov  rax, qword ptr [r15+2B0h]              ; r15 = Vcb (volume device extension)
    lea  rdx, [Ntfs_base]
    mov  rax, qword ptr [rdx+rax*8+5E7D8h]      ; table lookup
    lea  rcx, [Ntfs!NtfsFileIsInExpression]
    cmp  rax, rcx
    jne  Ntfs!FindNextIndexEntry2+0x660         ; -> indirect call through rax

The table has exactly four entries:

Ntfs+5E7B8:  DummyContainsWildcards   NtfsFileIsEqual           DummyContainsWildcards   NtfsTxfIdIsEqual
Ntfs+5E7D8:  DummyContainsWildcards   NtfsFileIsInExpression    DummyContainsWildcards   DummyContainsWildcards
Ntfs+5E7F8:  0000000000000000  <-- index 4 and beyond reads zero

Read from the kernel dump at crash time:

[Vcb+0x2B0] = 0x0000000000060001      expected 0x0000000000000001

The low 16 bits still hold the correct value 1 (file name index). Bits 16-31 have been overwritten with 6. So the index becomes 0x60001, the lookup lands Ntfs_base + 0x35E7E0, still inside the image, reads zero, and NTFS calls address 0. Kernel CFG catches the invalid indirect transfer and bugchecks. Verified in the debugger:

0: kd> dq Ntfs+5e7d8+8*poi(<Vcb>+2b0) L1
fffff807`81b1e7e0  00000000`00000000

trap frame: rax=0  ->  r10 = rax>>9 = 0  ->  faulting insn mov r11,[r11+r10*8]
            r11 = 0FBFF84A7E6040BD8h == the immediate baked into
                  nt!KscpCfgDispatchUserCallTargetEsSmep, i.e. kernel code intact

That is a 2-byte-offset partial overwrite of a live NTFS VCB field, not a bit flip and not a wild pointer. Once that qword is corrupted, the next wildcard directory enumeration anywhere on the volume detonates. That is why the crashing process is always a short-lived one that happens to enumerate a directory early in its life (a starting python or pwsh scanning module paths). The victim process is unrelated to the culprit.

My two stacks show the plain top-level path with the Wof pre-callback already returned:

nt!NtQueryDirectoryFile+0xe0
nt!IopSynchronousServiceTail+0x1c5
FLTMGR!FltpDispatch+0x244
FLTMGR!FltpLegacyProcessingAfterPreCallbacksCompleted+0x3fe    <-- pre-callbacks done, incl. Wof
Ntfs!NtfsFsdDirectoryControl+0xcb
Ntfs!NtfsCommonDirectoryControl+0x2ce
Ntfs!NtfsQueryDirectory+0xd32
Ntfs!NtfsContinueIndexEnumeration+0x10e
Ntfs!FindNextIndexEntry2+0x675
nt!KscpCfgDispatchUserCallTargetEsSmep+0x11
nt!KiGeneralProtectionFault+0x365
nt!guard_icall_handler+0x1e
nt!KeBugCheckEx

This is the downstream NTFS-victim variant described in the MS Q&A thread, and the corrupted VCB field is the missing link between the two.

Hardware ruled out

Worth stating because this bugcheck usually gets blamed on RAM or CPU, and this box runs an i9-14900HX with an aggressive turbo policy, which is the obvious false suspect:

  • Hardware sensor log, 9 minutes before crash 2: CPU total load avg 3.7%, max 18.8%, memory load 14%. The machine was idle.
  • Zero machine check / MCE events in WHEA over 30 days. The only WHEA entries are corrected PCIe AER warnings on an unrelated root port.
  • The corrupted value is a written 6, and the low half of the field is intact. Bit flips do not do that.
  • Same signature, same offset, on hardware completely different from the original reporter's.
Trigger correlation

Crash 1 landed 14 minutes into a Defender scheduled Quick Scan while agent work was running (CPU 61% avg in that window). Consistent with the concurrency theory in this thread: it needs overlapping directory enumerations, and a background scanner plus parallel agent tool calls is exactly that.

Status

Wof.sys shipped in the July 2026 CU still carries the defect. Compact OS being off does not prevent it, confirming the earlier finding in this thread.

For anyone triaging their own dumps, the fast check is !analyze -v giving 0x139_a_GUARD_ICALL_CHECK_FAILURE with Ntfs!FindNextIndexEntry2+0x675, then reading [Vcb+0x2B0]: anything other than a small integer 0-3 is this bug.

JohannOosthuizen · 1 month ago

Further work-around currently under way as follows by updating the projects claude.md, unfortunately the cost is avoiding sub-agent delegation.

Wof.sys BSOD avoidance (Windows — do not remove)

This machine has a kernel-driver defect (Wof.sys) that bugchecks under concurrent
NTFS directory enumeration. To minimize Claude Code's own contribution:

  • Never dispatch broad-search subagents (Explore, or Agent tasks that "search/

sweep/find across the codebase"). Do targeted, path-specific lookups yourself.

  • Never run a build/test/long-enumerating command (flutter, dart, npm,

recursive grep/find) while any other filesystem work is in flight. Do them
strictly one at a time, and say so before starting.

  • Avoid recursive/wide enumeration: no **/* globs, no ls -R, no grep -r.

Prefer a known path + single-file Read. If a search is unavoidable, rg --threads 1.

ELBALAZO94 · 1 month ago

<html>
<body>
<!--StartFragment--><html><head></head><body><p>Adjacent data point, and one correction to how the stack in this report is being attributed. I want to be explicit up front: <strong>I am not claiming to reproduce the signature in this issue.</strong> My dumps do not contain <code>Wof</code> frames, so my case is probably a different failure with the same architectural shape. I am posting it because two of its properties are directly relevant to the triage here.</p>
<h2>1. <code>Wof!...+0x695</code> is a return address, not the faulting instruction</h2>
<p>WinDbg prints frames callee-first. Re-reading the stack in the original report:</p>
<pre><code class="language-text">nt!KeBugCheckEx
nt!guard_icall_handler+0x1e
nt!KscpCfgDispatchUserCallTargetEsSmep+0x11
Ntfs!FindNextIndexEntry2+0x675 &lt;-- CFG guard fires HERE
Ntfs!NtfsContinueIndexEnumeration+0x10e
Ntfs!NtfsQueryDirectory+0xd32
FLTMGR!FltpLegacyProcessingAfterPreCallbacksCompleted+0x3fe
FLTMGR!FltPerformSynchronousIo+0x443
Wof!WofPreDirectoryControlCallback+0x695 &lt;-- return address of the FltPerformSynchronousIo call
FLTMGR!FltpPerformPreCallbacksWorker+0x58f
nt!NtQueryDirectoryFileEx+0xd8
</code></pre>
<p>The invalid indirect-call target is dispatched inside <code>Ntfs!FindNextIndexEntry2+0x675</code>. <code>Wof!WofPreDirectoryControlCallback+0x695</code> is the site from which WOF issues a <strong>re-entrant synchronous</strong> directory enumeration through FLTMGR. WOF is therefore on the triggering path, but this excerpt does not establish that the defective instruction is inside <code>Wof.sys</code> — the <code>FAILURE_BUCKET_ID</code> names WOF because it is the owning minifilter frame.</p>
<p>Consequences for triage:</p>
<ul>
<li>"Same offset across 14 crashes" establishes one repeatedly reachable <strong>call path</strong>, not by itself a code defect in WOF. A deterministic path consuming one poisoned structure reproduces the same offset every time. This also weakens the counter-argument in the MS Q&amp;A thread that four distinct bugchecks imply random hardware corruption — one path plus one bad datum produces exactly that spread.</li>
<li>The suspect set is wider than <code>Wof.sys</code>: NTFS directory-index enumeration, the context passed through the nested I/O request, persistent on-volume index/reparse-point state, and <strong>any other minifilter that hooks <code>IRP_MJ_DIRECTORY_CONTROL</code> on reparse-point-backed files</strong>.</li>
</ul>
<p>That last item is where my case lands.</p>
<h2>2. What my case actually shows — and what it does not</h2>
<p>Eight analyzed kernel minidumps, 16–23 July 2026, Windows 11 25H2 build <code>26200.8894</code>. Two properties matter:</p>
<p><strong>(a) The crashing user-mode process varied.</strong> <code>claude.exe</code>, <code>git.exe</code>, <code>powershell.exe</code>, <code>OneDrive.exe</code>. One crash occurred immediately after importing a skill ZIP via Claude Desktop, with <code>git.exe</code> as the active process. <strong>Claude Code was not a necessary condition on my machine.</strong> I am stating that plainly because it is evidence <em>against</em> attributing my BSODs to Claude Code, and anyone reading this thread should weight my report accordingly.</p>
<p><strong>(b) No <code>Wof</code> frames; recurring <code>Ntfs.sys</code> + <code>FLTMGR.SYS</code>.</strong> <code>compact /CompactOS:query</code> reported the system was <strong>not</strong> in a Compact state before the reinstall, so the WOF amplifier documented in this issue was absent on my machine. What I did have attached to <code>C:</code> was <code>CldFlt</code> (OneDrive cloud-files placeholder filter) — architecturally the same pattern as WOF: a minifilter that intercepts directory control on files backed by reparse points, and that can issue nested I/O to hydrate or fix up metadata. <code>OneDrive.exe</code> appearing as the active process in one dump is consistent with that path being involved, though I have not symbolized the dumps far enough to prove it.</p>
<p>So the useful reading of my data is not "WOF confirmed" but: <strong>the same nested-enumeration architecture exists for more than one Microsoft minifilter, and a broad recursive glob is enough to load it heavily.</strong> My reproduction trigger was a single broad pattern allowed outside the active workspace:</p>
<pre><code class="language-text">**/conductor
</code></pre>
<h2>3. Format vs. in-place — the one contrast worth testing</h2>

Action | Replaces Wof.sys / Ntfs.sys | Rebuilds $MFT / $I30 | Resets reparse points + filter/app state | Observed outcome
-- | -- | -- | -- | --
Disable WSearch | No | No | No | No improvement
Disable HP One Agent | No | No | Partial | No improvement
Mutex / serialized tool I/O | No | No | No | Reduced exposure; crashes not eliminated
In-place reinstall from ISO | Yes | No | No | No improvement (reported by OP)
Clean install, partition deleted + formatted | Yes | Yes | Yes | 0 BSODs so far

<p>Recurring offsets in the analyzed dumps (see version caveat above):</p>
<pre><code class="language-text">Ntfs.sys +0x115AC5 +0x1157BB +0x11517E +0x2684F2 +0x1CABCE +0x1CA89B
FLTMGR.SYS +0xC70E +0x1C5F0 +0x1C0E4
</code></pre>
<p>Diagnostics completed before the reinstall, all clean: HP extended memory test (45 iterations, 6 h 24 min, zero errors); processor diagnostics passed; <code>DISM /Online /Cleanup-Image /RestoreHealth</code>; <code>sfc /scannow</code>; <code>chkdsk C: /scan</code> (online scan only — see §3); SSD SMART with <code>Critical Warning = 0</code>, <code>Media and Data Integrity Errors = 0</code>, <code>Error Information Log Entries = 0</code>, <code>Available Spare = 100%</code>, <code>Percentage Used = 6%</code>. All observed minifilters were Microsoft-signed, which narrows but does not exclude filter involvement.</p>
<p>Dumps retained in backup:</p>
<pre><code class="language-text">071626-13093-01.dmp 071626-21953-01.dmp 072026-15968-01.dmp 072026-20593-01.dmp
072026-20843-01.dmp 072126-13312-01.dmp 072126-13953-01.dmp 072326-14406-01.dmp
</code></pre>
&lt;/details&gt;
<p>I still have all eight pre-reinstall minidumps and can provide them privately, along with WinDbg output, Event Viewer exports, SMART data and <code>fltmc</code> output. Given §2(a), the most valuable thing in them is probably the <strong>non-Claude</strong> crashes: if <code>git.exe</code> and <code>OneDrive.exe</code> reach the same NTFS/FLTMGR path, that is a datum this thread does not currently have.</p></body></html><!--EndFragment-->
</body>
</html>/

LeitchP · 1 month ago

Additional data: reproduced with Wof.sys disabled and with zero third-party filesystem filters loaded. Register state matches @dxdum's corrupted-Vcb mechanism exactly.

I have included a replication test at the end which caused the problem within 20 minutes or so every time I ran it.

Alienware m18 R2 (third in this thread), i9-14900HX, Windows 11 24H2 build 26100.8875. 19 minidumps decoded, all one signature: 0x139 P1=0xA in NTFS directory enumeration, stack offsets matching those reported above (Ntfs +0x115AC5 / +0x1157BB / +0x11517E / +0x2684F2, FLTMGR +0xC70E). Trap-context registers in all 19 dumps: RAX=0, R10=0, R11=0xFBFF... — i.e. a null call target from the over-indexed comparison-routine table, consistent with the [Vcb+0x2B0] corruption @dxdum documented. (The page-aligned RCX values are the enumeration buffer argument.)

Elimination sequence, each step verified by reproduction afterwards:

| Change | Result |
|---|---|
| BIOS 1.23.0 (latest) | crash persists |
| CPU capped to base clocks | crash persists |
| Wof.sys disabled (Start=4, absent from fltmc) | crash persists, same stack |
| All third-party FS filters removed (Norton), pure Microsoft stack + Defender | crash persists, same stack |
| Drive SMART / memory at JEDEC | clean / at spec |
| KB5101650 uninstalled (Wof.sys reverts to 10.0.26100.1) | daily-crash regression resolved: same reproduction ran 2 h clean vs 9-21 min to bugcheck before |

So on this machine the failure needs no Wof and no third-party filter; whichever filter is in-frame is a bystander to the shared NTFS path. Reproduction without claude.exe: looping compact /q /s full-drive walks alongside normal background activity bugchecks it in 10 to 20 minutes.

Timeline matches @rzinnatullin and @Andre-Erasmus: KB5101650 installed 17 Jul, daily crashes from 19 Jul (sporadic same-machine BSODs since late March predate it). Crash frequency also tracks Claude Code usage intensity, consistent with concurrent Glob/Grep enumeration as the dominant trigger; CLAUDE_CODE_MAX_TOOL_USE_CONCURRENCY=1 reduces exposure only.

Test Script

Same workload (script below), 3 controlled runs:

| Build state | Result |
|---|---|
| 26100.8875, Norton present | bugcheck lap 4, ~10 min |
| 26100.8875, pure Microsoft filter stack | bugcheck lap 9, ~21.5 min |
| KB5101650 uninstalled, Wof.sys 10.0.26100.1 | 120 min, no bugcheck |

Roughly 6x the longest pre-rollback survival with zero faults, on the identical trigger. Note the scope: this resolves the daily-crash regression introduced with the July servicing; the sporadic pre-July crashes on this machine (~fortnightly since late March) imply the latent defect predates KB5101650, so the rollback is a mitigation, not proof the older binaries are clean. Will retest on the August cumulative and report.

 ============================================================
#  walk-test-rollback.ps1
#  Reproduction test for the 0x139 NTFS enumeration bug,
#  post-KB5101650-rollback run.
#
#  Loops full-drive directory walks (the known 10-20 minute
#  trigger) for a maximum of 2 hours, logging every lap to
#  C:\ProgramData\walk-log-rollback.txt so a crash preserves
#  the record. Stops itself cleanly at the time limit.
#
#  Run as Administrator. Ctrl+C stops it early.
# ============================================================
 
$log      = 'C:\ProgramData\walk-log-rollback.txt'
$maxHours = 2
$drives   = 'C','D','E'
 
$start = Get-Date
$deadline = $start.AddHours($maxHours)
 
$wof = (Get-Item C:\Windows\System32\drivers\Wof.sys -ErrorAction SilentlyContinue).VersionInfo.FileVersion
$kb  = if (Get-HotFix -Id KB5101650 -ErrorAction SilentlyContinue) { 'PRESENT' } else { 'absent' }
 
$hdr = "RUN START {0}  (rollback test; KB5101650={1}; Wof.sys={2}; max {3}h)" -f `
       $start.ToString('yyyy-MM-dd HH:mm:ss'), $kb, $wof, $maxHours
Write-Host $hdr; Add-Content $log $hdr
 
$lap = 0
while ((Get-Date) -lt $deadline) {
    $lap++
    foreach ($d in $drives) {
        if ((Get-Date) -ge $deadline) { break }
        $m = "lap {0}  {1}:  start {2}" -f $lap, $d, (Get-Date -Format 'HH:mm:ss')
        Write-Host $m; Add-Content $log $m
        compact /q /s:"${d}:\" /i 2>$null | Select-Object -Last 1 | Out-Null
        $m = "lap {0}  {1}:  done  {2}" -f $lap, $d, (Get-Date -Format 'HH:mm:ss')
        Write-Host $m; Add-Content $log $m
    }
}
 
$mins = [math]::Round(((Get-Date) - $start).TotalMinutes, 1)
$end = "RUN COMPLETE {0}  ({1} laps, {2} minutes, no bugcheck)" -f `
       (Get-Date -Format 'yyyy-MM-dd HH:mm:ss'), $lap, $mins
Write-Host $end -ForegroundColor Green; Add-Content $log $end
geoffschaeffer · 1 month ago

<html>
<body>
<!--StartFragment--><p class="font-claude-response-body break-words whitespace-normal" dir="ltr" data-sourcepos="1:1-1:119;0-118">Adding a fourth i9-14900HX data point, and confirming the register signature described above on two independent dumps.</p>

<p class="font-claude-response-body break-words whitespace-normal" dir="ltr" data-sourcepos="3:1-3:156;120-275"><strong>System:</strong> Acer laptop, Intel Core i9-14900HX (32 logical processors), Windows 11 24H2 <strong>build 26100</strong>, Wof.sys <strong>10.0.26100.8875</strong> (i.e. post-KB5101650).</p>

<p class="font-claude-response-body break-words whitespace-normal" dir="ltr" data-sourcepos="5:1-5:218;277-494"><strong>Crashes:</strong> two, 17 minutes apart, both while Claude Code ran directory enumeration over a Unity project (large <code class="bg-text-200/5 border border-0.5 border-border-300 text-danger-000 whitespace-pre-wrap rounded-[0.4rem] px-1 py-px text-[0.9rem]">Library/</code> tree). Process <code class="bg-text-200/5 border border-0.5 border-border-300 text-danger-000 whitespace-pre-wrap rounded-[0.4rem] px-1 py-px text-[0.9rem]">find.exe</code> via <code class="bg-text-200/5 border border-0.5 border-border-300 text-danger-000 whitespace-pre-wrap rounded-[0.4rem] px-1 py-px text-[0.9rem]">NtQueryDirectoryFile</code>. No crashes on this machine before this.</p>

<h3 dir="ltr" class="text-text-100 mt-2 -mb-1 text-base font-bold" data-sourcepos="7:1-7:75;496-570">Register signature — matches the corrupted-Vcb mechanism on both dumps</h3>

<p class="font-claude-response-body break-words whitespace-normal" dir="ltr" data-sourcepos="9:1-9:212;572-783">WinDbg analyzed only the second dump, so I extracted the <code class="bg-text-200/5 border border-0.5 border-border-300 text-danger-000 whitespace-pre-wrap rounded-[0.4rem] px-1 py-px text-[0.9rem]">KTRAP_FRAME</code> from the first one manually (located at stack <code class="bg-text-200/5 border border-0.5 border-border-300 text-danger-000 whitespace-pre-wrap rounded-[0.4rem] px-1 py-px text-[0.9rem]">+0x1098</code> in both; field offsets calibrated against the known-good WinDbg values from dump 2).</p>

<div dir="ltr" class="overflow-x-auto w-full px-2 mb-6 print:overflow-x-visible" data-sourcepos="11:1-17:63;785-1103">
  | crash 1 (072826-21078-01) | crash 2 (072826-20843-01)
-- | -- | --
RAX | 0x0 | 0x0
R10 | 0x0 | 0x0
R11 | 0xfbffd03cd775ddd8 | 0xfbffdc7615ad6d78
RCX (page-aligned buffer arg) | 0xffff808b2d656000 | 0xffff938a5aa02000
RIP | nt!KscpCfgDispatchUserCallTargetEsSmep+0x11 | same

</div>

<p class="font-claude-response-body break-words whitespace-normal" dir="ltr" data-sourcepos="19:1-19:160;1105-1264">Null call target, <code class="bg-text-200/5 border border-0.5 border-border-300 text-danger-000 whitespace-pre-wrap rounded-[0.4rem] px-1 py-px text-[0.9rem]">0xFBFF...</code> guard-bitmap address, page-aligned RCX — consistent with the <code class="bg-text-200/5 border border-0.5 border-border-300 text-danger-000 whitespace-pre-wrap rounded-[0.4rem] px-1 py-px text-[0.9rem]">[Vcb+0x2B0]</code> over-indexed comparison-routine table described above.</p>

<p class="font-claude-response-body break-words whitespace-normal" dir="ltr" data-sourcepos="21:1-21:30;1266-1295">Faulting instruction in both:</p>

<div role="group" aria-label="Code" tabindex="0" data-sourcepos="23:1-26:4;1297-1428" class="relative group/copy bg-bg-000/50 border-0.5 border-border-400 rounded-lg focus:outline-none focus-visible:ring-2 focus-visible:ring-accent-100"><div class="sticky opacity-0 group-hover/copy:opacity-100 group-focus-within/copy:opacity-100 top-2 py-2 h-12 w-0 float-right"><div class="absolute right-0 h-8 px-2 items-center inline-flex z-10"></div></div><div class="overflow-x-auto"><pre class="code-block__code !my-0 !rounded-lg !text-sm !leading-relaxed p-3.5" style="color: rgb(20, 24, 31); background: transparent; font-family: var(--font-mono);"><code style="color: rgb(20, 24, 31); background: transparent; font-family: var(--font-mono); white-space: pre-wrap;">nt!KscpCfgDispatchUserCallTargetEsSmep+0x11:
4f8b1cd3 mov r11,qword ptr [r11+r10*8] ds:fbffdc76`15ad6d78=????????????????</code></pre></div></div>

<h3 dir="ltr" class="text-text-100 mt-2 -mb-1 text-base font-bold" data-sourcepos="28:1-28:18;1430-1447">Stack offsets</h3>

<p class="font-claude-response-body break-words whitespace-normal" dir="ltr" data-sourcepos="30:1-30:185;1449-1633">Present in both dumps: <code class="bg-text-200/5 border border-0.5 border-border-300 text-danger-000 whitespace-pre-wrap rounded-[0.4rem] px-1 py-px text-[0.9rem]">Ntfs +0x115AC5</code>, <code class="bg-text-200/5 border border-0.5 border-border-300 text-danger-000 whitespace-pre-wrap rounded-[0.4rem] px-1 py-px text-[0.9rem]">Ntfs +0x11517E</code>, <code class="bg-text-200/5 border border-0.5 border-border-300 text-danger-000 whitespace-pre-wrap rounded-[0.4rem] px-1 py-px text-[0.9rem]">Ntfs +0x2684F2</code>, <code class="bg-text-200/5 border border-0.5 border-border-300 text-danger-000 whitespace-pre-wrap rounded-[0.4rem] px-1 py-px text-[0.9rem]">FLTMGR +0xC70E</code>. <code class="bg-text-200/5 border border-0.5 border-border-300 text-danger-000 whitespace-pre-wrap rounded-[0.4rem] px-1 py-px text-[0.9rem]">Ntfs +0x1157BB</code> appears in crash 1; crash 2 has <code class="bg-text-200/5 border border-0.5 border-border-300 text-danger-000 whitespace-pre-wrap rounded-[0.4rem] px-1 py-px text-[0.9rem]">Ntfs +0x1148E1</code> at the same stack slot.</p>

<p class="font-claude-response-body break-words whitespace-normal" dir="ltr" data-sourcepos="32:1-32:192;1635-1826">I compared the two dumps frame-by-frame by module+offset (ASLR-independent): <strong>identical at the same stack offsets from <code class="bg-text-200/5 border border-0.5 border-border-300 text-danger-000 whitespace-pre-wrap rounded-[0.4rem] px-1 py-px text-[0.9rem]">+0x0810</code> through <code class="bg-text-200/5 border border-0.5 border-border-300 text-danger-000 whitespace-pre-wrap rounded-[0.4rem] px-1 py-px text-[0.9rem]">+0x1b80</code></strong>, 67 frames in common. Deterministic path.</p>

<h3 dir="ltr" class="text-text-100 mt-2 -mb-1 text-base font-bold" data-sourcepos="34:1-34:63;1828-1890">Corroborating the "filter in frame is a bystander" finding</h3>

<p class="font-claude-response-body break-words whitespace-normal" dir="ltr" data-sourcepos="36:1-36:627;1892-2518">My dumps independently support this from the other direction. Crash 1 contained a single Norton driver address (<code class="bg-text-200/5 border border-0.5 border-border-300 text-danger-000 whitespace-pre-wrap rounded-[0.4rem] px-1 py-px text-[0.9rem]">nllbidsdriver.sys+0x58df8</code>) on the stack, which initially looked like a lead. Crash 2 contained <strong>no third-party driver frames at all</strong> — and the Norton address in crash 1 sat at stack offset <code class="bg-text-200/5 border border-0.5 border-border-300 text-danger-000 whitespace-pre-wrap rounded-[0.4rem] px-1 py-px text-[0.9rem]">+0x0b38</code>, inside the region where the two stacks diverge, i.e. stale stack data rather than a live frame. A pointer census across the whole dump confirmed it: every loaded driver has a baseline of 3 self-references from its own entry in the driver table, and <code class="bg-text-200/5 border border-0.5 border-border-300 text-danger-000 whitespace-pre-wrap rounded-[0.4rem] px-1 py-px text-[0.9rem]">nllbidsdriver.sys</code> had exactly 4 — the one stale stack slot.</p>

<p class="font-claude-response-body break-words whitespace-normal" dir="ltr" data-sourcepos="38:1-38:456;2520-2975">WinDbg bucketed my crash 2 as <code class="bg-text-200/5 border border-0.5 border-border-300 text-danger-000 whitespace-pre-wrap rounded-[0.4rem] px-1 py-px text-[0.9rem]">0x139_a_GUARD_ICALL_CHECK_FAILURE_Wof!WofPreDirectoryControlCallback</code> (<code class="bg-text-200/5 border border-0.5 border-border-300 text-danger-000 whitespace-pre-wrap rounded-[0.4rem] px-1 py-px text-[0.9rem]">BUCKET_ID_FUNC_OFFSET: 695</code>), but given the report above that the crash reproduces with Wof.sys disabled entirely, that attribution looks like the same bystander effect — <code class="bg-text-200/5 border border-0.5 border-border-300 text-danger-000 whitespace-pre-wrap rounded-[0.4rem] px-1 py-px text-[0.9rem]">Wof!WofPreDirectoryControlCallback+0x695</code> is simply the frame that issued the synchronous directory query via <code class="bg-text-200/5 border border-0.5 border-border-300 text-danger-000 whitespace-pre-wrap rounded-[0.4rem] px-1 py-px text-[0.9rem]">FltPerformSynchronousIo</code> before control reached the shared NTFS path.</p>

<h3 dir="ltr" class="text-text-100 mt-2 -mb-1 text-base font-bold" data-sourcepos="40:1-40:16;2977-2992">Other notes</h3>

<ul dir="ltr" class="[li_&amp;]:mb-0 [li_&amp;]:mt-1 [li_&amp;]:gap-1 [&amp;:not(:last-child)_ul]:pb-1 [&amp;:not(:last-child)_ol]:pb-1 list-disc flex flex-col gap-1 pl-8 mb-3 print:block print:space-y-1" data-sourcepos="42:1-44:115;2994-3311">
<li class="font-claude-response-body whitespace-normal break-words pl-2" data-sourcepos="42:1-42:84;2994-3077"><code class="bg-text-200/5 border border-0.5 border-border-300 text-danger-000 whitespace-pre-wrap rounded-[0.4rem] px-1 py-px text-[0.9rem]">chkdsk C: /scan</code> clean (1.16M file records, 28,274 reparse points, no problems).</li>
<li class="font-claude-response-body whitespace-normal break-words pl-2" data-sourcepos="43:1-43:119;3078-3196">Build 26100 here, vs 26200 in the earlier reports in this thread — so the defect is not specific to the 25H2 branch.</li>
<li class="font-claude-response-body whitespace-normal break-words pl-2" data-sourcepos="44:1-44:115;3197-3311">Wof.sys 10.0.26100.8875 still faults at the same offset, consistent with the KB5101650 timeline described above.</li>
</ul>

<p class="font-claude-response-body break-words whitespace-normal" dir="ltr" data-sourcepos="46:1-46:58;3313-3370"><code class="bg-text-200/5 border border-0.5 border-border-300 text-danger-000 whitespace-pre-wrap rounded-[0.4rem] px-1 py-px text-[0.9rem]">FAILURE_ID_HASH: {78ac0991-5393-0281-b23b-ce115373dc6d}</code></p>

<p class="font-claude-response-body break-words whitespace-normal" dir="ltr" data-sourcepos="48:1-48:42;3372-3413">Happy to attach both minidumps if useful.</p><!--EndFragment-->
</body>
</html>

emelmusti83-sys · 27 days ago

Additional reproduction after KB5101650 — three identical BSODs through Claude Code UI

I am experiencing the same Wof.sys directory-enumeration crash described in this issue.

Environment

  • Windows 11 Pro 25H2 x64
  • OS build: 26200.8875
  • Installed cumulative update: KB5101650
  • Device: ASUS ROG Strix SCAR 18 G834JYR
  • RAM: 32 GB
  • Claude usage: Claude Code UI inside the Windows Claude application
  • Security software: McAfee
  • sfc /scannow: no integrity violations found

Regression timing

Claude Code previously worked on this same computer without causing BSODs.

The crashes began after KB5101650 was installed. This does not prove that the Windows update is the root cause, but the timing may be relevant because all three crashes after the update fail in the same WOF directory-control path.

Reproduction pattern

  1. Start Windows normally.
  2. Leave Claude Code closed.
  3. The system remains stable during ordinary desktop use and gaming.
  4. Open the Claude Code UI.
  5. Open an existing local development project.
  6. Allow Claude Code to inspect or scan the project.
  7. Within approximately 1–2 minutes, the system either:
  • crashes with a BSOD, or
  • freezes completely and requires a forced shutdown.

I have stopped intentionally reproducing it because it has already caused multiple kernel crashes.

Crash information

I experienced three recent BSODs:

  • 2026-07-31
  • 2026-08-01
  • 2026-08-01

All three generated the same bugcheck and arguments:

KMODE_EXCEPTION_NOT_HANDLED (0x1E)

Arg1: ffffffffc0000005
Arg2: 0000000000000000
Arg3: 0000000000000008
Arg4: 0000000000000000

The diagnostic information consistently points to:

FAILURE_BUCKET_ID: AV_Wof!WofPreDirectoryControlCallback
Exception code: 0xC0000005

The filesystem path includes:

NtQueryDirectoryFileEx
FLTMGR.SYS
Ntfs.sys
Wof!WofPreDirectoryControlCallback

Processes recorded as active during the crashes:

powershell.exe — one crash
dotnet.exe     — two crashes

The system remains stable when Claude Code is not running.

Possible mitigation request

Could Claude Code reduce or serialize concurrent directory-enumeration operations on affected Windows systems?

Potential mitigations could include:

  • throttling intensive directory scans on Windows;
  • limiting concurrent NtQueryDirectoryFileEx operations;
  • providing a configurable filesystem scan-concurrency limit;
  • adding a Windows filesystem safe mode;
  • detecting affected Windows or Wof.sys versions and warning the user.

I have the following diagnostics available:

  • three minidump files;
  • sanitized WinDbg results;
  • msinfo32 system information;
  • Windows System and Application event logs;
  • installed driver list;
  • fltmc filesystem-filter lists.

I am not uploading the complete diagnostic archive publicly because dumps and event logs may contain usernames and local file paths, but I can provide specific sanitized sections if requested.

LeitchP · 27 days ago

@emelmusti83-sys Your report slots cleanly into the pattern established above, including the bugcheck difference. 0x1E with 0xC0000005 is one of the 4 documented manifestations of this same defect (0x139 / 0x3B / 0x1E / 0x50, per the original report): the corrupted call target sometimes gets caught by CFG (0x139) and sometimes escapes into an access violation (your 0x1E). Same path, same Wof!WofPreDirectoryControlCallback bucket, and per the elimination testing earlier in this thread, the Wof frame is a bystander to a shared NTFS enumeration defect. Your onset timing after KB5101650 matches @rzinnatullin, @Andre-Erasmus and my machine (installed 17 Jul, daily crashes from 19 Jul). Your active-process spread (powershell.exe, dotnet.exe) also fits: once the volume structure is poisoned, whichever process enumerates next takes the crash.

Two things you can act on today.

1. Uninstall and block KB5101650. This is what stopped the daily crashes on my machine, and I verified it with a controlled reproduction rather than just waiting: the identical workload that bugchecked in 10-21 minutes on 26100.8875 ran 24 laps / 66 minutes clean after the rollback (Wof.sys reverted to 10.0.26100.1). Procedure, learned the hard way because the update reinstalled itself on my first attempt:

# If BitLocker is enabled, suspend it for the uninstall reboot:
Suspend-BitLocker -MountPoint "C:" -RebootCount 1

# Uninstall (triggers a reboot):
wusa /uninstall /kb:5101650
# If this errors with 0x800f0825, an update is staged pending reboot.
# Restart first, then run the uninstall again.

After the reboot, immediately close the roads back, in this order:

# 1. Pause updates: Settings > Windows Update > Pause updates, pick a date past 12 Aug.

# 2. Purge any staged copy so it cannot install on the next reboot:
net stop wuauserv; net stop bits
Remove-Item C:\Windows\SoftwareDistribution\Download\* -Recurse -Force
net start bits; net start wuauserv

# 3. Notify-only policy: nothing auto-installs, ever, until you reverse it:
New-Item 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU' -Force | Out-Null
Set-ItemProperty 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU' -Name AUOptions -Type DWord -Value 2

Notes from my attempt: do not rely on Hide-WindowsUpdate alone (it hangs while updates are paused, and a name-based hide is useless against the August cumulative, which will carry the same binaries under a new KB number if unfixed). The pause plus AUOptions=2 covers both. Verify the end state:

Get-HotFix -Id KB5101650                                            # should error: not found
(Get-Item C:\Windows\System32\drivers\Wof.sys).VersionInfo.FileVersion   # should be below .8875

Reverse the policy later by deleting the AU registry key; reinstall the update whenever a fixed build ships by resuming updates.

2. Use the reproduction script in my comment above as your measurement tool. I understand not wanting to crash the machine again, so run it in whichever mode suits your risk tolerance: post-rollback only, where a 60-120 minute clean run is your evidence the rollback worked (it should not crash); or once before and once after if you want the same controlled before/after I posted. Crashes from it are ordinary bugchecks, NTFS journalling handles them, but that call is yours, especially without full backups.

On your mitigation requests: a concurrency lever already exists, CLAUDE_CODE_MAX_TOOL_USE_CONCURRENCY=1 set as a user environment variable reduces exposure (it cannot eliminate it, since other enumerators on the volume still contribute). See also the hooks-based serialisation workaround posted by @JohannOosthuizen above, and PR #35710 for the in-product fix. But on a machine crashing within 1-2 minutes of opening Claude Code, the rollback is the intervention with measured results; the throttles are for those staying on the July binaries.

LeitchP · 24 days ago

10-day follow-up on the KB5101650 rollback: zero bugchecks

Status update on the machine from my earlier comments (Alienware m18 R2, i9-14900HX, 24H2, rolled back to Wof.sys / Ntfs.sys 10.0.26100.1 on 28 Jul):

Current uptime      : 7d 22h 48m
Last bugcheck       : Tue 28 Jul 21:43  (9d 21h ago — the final pre-rollback crash)
Since rollback      : 9d 21h clean, zero bugchecks, zero unclean shutdowns (event 41)

Context for those numbers: on the KB5101650 binaries this machine was averaging ~1.3 bugchecks/day (19-28 Jul), and the controlled reproduction crashed it in 10-21 minutes on demand. At that rate, 10 silent days had odds of roughly 1 in 30,000, so the July regression is dead on this machine, not merely quieter. Notably the clean run includes daily Claude Code use in VS Code with no concurrency throttling (CLAUDE_CODE_MAX_TOOL_USE_CONCURRENCY removed), no serialization hooks, and no CompactOS/Wof changes — the rollback alone.

One honest caveat: this machine also had sporadic same-path crashes (~fortnightly, March-July) predating KB5101650, and 10 days cannot yet distinguish "gone" from "back to fortnightly" for that older, slower rate. The daily regression and the latent defect remain separate questions.

Plan: the August cumulative gets installed manually next week (updates are on a notify-only policy per my earlier comment), then the same reproduction script runs against it. Pass = report here and everything gets restored; fail = it comes off the same way KB5101650 did. Either result posted with lap counts.

ksx-kshan · 17 days ago

Windows update 9168 seems to resolve this for me, so far. Might be worth a try.

Windows 11 25H2 — NTFS/Wof directory-enumeration BSOD

BEFORE: Build 26200.8894 (KB5121767, on top of KB5101650 / 26200.8875)
AFTER: Build 26200.9168 (KB5121003, 2026-08-11 Patch Tuesday)

ntfs.sys
component: amd64_microsoft-windows-ntfs_31bf3856ad364e35 8875 -> 9168
before SHA256: B340816E8F307030247D624D746437B2CA1133664C6261DF1376B5829CB69380 (2026-07-14 23:10)
after SHA256: 24B023140A6D162DB3FE0D701109FC0BE4FDD9EC65E1C40522934AE3CC0A28C6 (2026-08-11 16:50)

Wof.sys
component: amd64_microsoft-windows-overlayfilter_31bf3856ad364e35 8875 -> 8972
before SHA256: 065980458B88B99AE0C408A83FF1E3CBD87E7A10DBACBBD83981B497C20DB34B (2026-07-14 23:10)
after SHA256: 62EA99EC3FF37B223B2624B72CBC1D0F4362A358B7E21BFE53831859C2437F4A (2026-08-11 16:50)

Note: KB5121767 (26200.8894) did NOT change either binary — it bumped the build while
carrying both forward byte-identical. KB5121003 (26200.9168) is the first update to
actually replace them.

DaltonSalvatti · 15 days ago

Same bug family here, but with a different faulting frame — reporting in case it helps narrow down the defect.

Over 25 days I hit 10 BSODs, all with claude.exe as PROCESS_NAME (10/10), all during directory enumeration. My stack faults in Ntfs!FindNextIndexEntry2+0x675 rather than Wof!WofPreDirectoryControlCallback+0x695, but the bugcheck, mechanism and trigger match this report exactly.

Crash signature

BUGCHECK_CODE:      139 (also one 0x3B)
BUGCHECK_P1:        a          -> Indirect call guard check detected invalid control transfer
SYMBOL_NAME:        nt!guard_icall_handler+1e
FAILURE_BUCKET_ID:  0x139_a_GUARD_ICALL_CHECK_FAILURE_nt!guard_icall_handler
PROCESS_NAME:       claude.exe   (10 of 10 crashes)

Stack (identical in every dump):

nt!KeBugCheckEx
nt!guard_icall_handler+0x1e
nt!RtlpExecuteHandlerForException+0xf
nt!RtlDispatchException+0x2d2
nt!KiDispatchException+0x35f
nt!KiExceptionDispatch+0x145
nt!KiGeneralProtectionFault+0x365
nt!KscpCfgDispatchUserCallTargetEsSmep+0x11
Ntfs!FindNextIndexEntry2+0x675          <-- faults here
Ntfs!NtfsContinueIndexEnumeration+0x10e
Ntfs!NtfsQueryDirectory+0xd32
Ntfs!NtfsCommonDirectoryControl+0x2ce
Ntfs!NtfsFsdDirectoryControl+0xcb
nt!IopfCallDriver+0x5b
FLTMGR!FltpLegacyProcessingAfterPreCallbacksCompleted+0x3fe
FLTMGR!FltpDispatch+0x244
nt!IopfCallDriver+0x5b
nt!IopSynchronousServiceTail+0x1c5
nt!NtQueryDirectoryFileEx+0xd8
nt!KiSystemServiceCopyEnd+0x25

The one 0x3B had the same stack, faulting at Ntfs!NtfsContinueIndexEnumeration+0 with 0xc0000005 — i.e. the same corrupted indirect target manifesting as an AV instead of tripping CFG.

Wof.sys is attached here too

Even though my frame is in Ntfs, WOF is loaded and attached to C: at the altitude named in this report:

Wof   40700   Wof Instance   (7 instances, C: attached)

Full minifilter set on C: — all Microsoft, no third-party AV or shell extensions:
bindflt, UCPD, WdFilter, gameflt, CldFlt, bfs, luafv, Wof, FileInfo

CompactOS was already disabled the whole time (compact /compactos:query → "system is not in the Compact state"), which corroborates the note in this thread that compact /CompactOS:never does not eliminate the crashes — WOF stays attached regardless.

Affected directories — not tied to a specific path

I extracted the target directory from each kernel dump via
!thread!irp <irp> 1!fileobj <OriginalFileObject>.

Four distinct directories across the 10 crashes:

| # | Directory | Files |
|---|---|---|
| 1 | ...\dasalldp\node_modules\rxjs\internal\util | 102 |
| 2 | ...\dasalldp\node_modules\rxjs\_esm5\internal\operators | 208 |
| 3 | ...\mydevbotapp\src\images\icons\material | 3,676 |
| 4 | ...\mydevbotmeet\node_modules | — |

Notes that may matter:

  • It is not a corrupted on-disk index. Every one of these directories enumerates perfectly via System.IO.Directory.GetFileSystemEntries — before and after the crashes. chkdsk /scan (repeatedly) and an offline chkdsk /f found no filesystem problems, and the volume was never dirty.
  • Deleting and recreating a directory does not fix it. I deleted dasalldp\node_modules and reinstalled it from scratch (npm install); it crashed again a few days later in a different rxjs subdirectory. I restored icons\material clean from git; it crashed on that same path twice afterwards.
  • Directory size is not the discriminator — 102 files and 3,676 files both trigger it.

Not reproducible sequentially — looks concurrency/timing dependent

I tried to reproduce on demand with ripgrep 15.0.0 against the exact directory that had just crashed the machine:

rg --files <crashing dir>                 # 3,676 files
rg --no-messages --hidden -n "viewBox" <crashing dir>
rg --files <whole src tree>               # 10,300 files

All three completed normally, three times, no crash. So a single sequential walk does not trigger it — consistent with the "dozens of concurrent directory walks" theory in this thread rather than a deterministic per-directory defect.

Hardware exhaustively ruled out

I went a long way down the hardware path before finding this issue, so I can add fairly strong negative evidence:

| Test | Result |
|---|---|
| Windows Memory Diagnostic | clean |
| Custom multithreaded RAM stress, 36 GB × 514 passes (~18 TB write+verify) | 0 bit errors |
| Same test, 12 GB × 2,826 passes (~34 TB) | 0 bit errors |
| CPU stress, 32 threads / 30 min, 16.7M verified iterations | 0 compute errors, 0 WHEA/MCE |
| chkdsk /scan (multiple) + offline chkdsk /f | no problems, volume never dirty |
| git fsck --full --strict, 8 repositories | no corruption |
| Replaced the RAM entirely (aftermarket 2×32 GB → factory 2×16 GB matched kit) | crashes continued |
| BIOS update (E15M2IMS .713 → .714) | crashes continued |
| HmbAllocationPolicy=0 (HMB off) | crashes continued |
| PCIe ASPM off + disk idle timeout off | crashes continued |

Every hardware hypothesis was falsified by a subsequent crash. This matches other reports here where "hardware checks all passed".

Environment

  • OS: Windows 11 25H2 — build 26200.8875 for all 10 crashes (now on 26200.9168 since Aug 14; too early to say whether it changes anything)
  • Wof.sys: 10.0.26100.8875, service Wof, Boot start
  • CPU: Intel Core i9-14900HX (24C/32T)
  • Machine: MSI Raider GE68 HX 14V (board MS-15M2), BIOS E15M2IMS.714
  • Storage: WD PC SN560 NVMe 1 TB (FW 74116000) behind Intel VMD/RST (iaStorVD 19.5.7.1058)
  • Workspace: multi-project monorepo — ~8 git repositories, several Angular projects with large node_modules

Frequency

10 crashes between Jul 21 and Aug 14, initially up to 2 per day, later spacing out to 6 and then 10 days apart. The spacing correlates with how much heavy scanning I was doing, not with any of the hardware changes above.

Suggestion

Adding to what was already proposed in this thread: since a single sequential rg walk provably does not trigger it here, throttling or serializing the concurrent NtQueryDirectoryFileEx bursts on Windows looks like it would be an effective client-side mitigation while the kernel-side issue is investigated.

Happy to share the kernel dumps or run any specific WinDbg commands against them if that would help.