Windows 11 BSOD 0x12E INVALID_MDL_RANGE in NTFS during sleep transition

Title: Windows 11 BSOD 0x12E INVALID_MDL_RANGE in NTFS during sleep transition

I'm investigating recurring BSODs on an ASUS TUF Gaming A17 FA707RE running Windows 11.

The latest crash occurred on October 11, 2026. Kernel-Power Event ID 41 reports BugcheckCode 302 (0x12E) with these parameters:

  • Arg1: 0xffffc788ba2bc060

  • Arg2: 0xffffc788ba2bcaf0

  • Arg3: 0xffffc788ba673000

  • Arg4: 0xffe01000

The event also reports SleepInProgress=6.

My WinDbg investigation identified an NTFS code path involving Ntfs!LfsFlushLfcb, Ntfs!LfsPrepareToWriteHeadOfTheLog, and IoBuildPartialMdl.

The MDL at ffffc788ba2bc060 reports ByteCount=0x11000, while the MDL at ffffc788ba2bcaf0 reports ByteCount=0x1000. The requested virtual address appears to be outside the first MDL's mapped range.

I have not determined whether NTFS generates the invalid range or whether the relevant metadata was corrupted earlier.

Could someone help analyze the dump and identify the likely source of the invalid MDL range?

Dump download link: [https://drive.google.com/file/d/1bQDfNt5cTfLOKuzD_Jc5eg8_oLa_oPud/view?usp=sharing\]

TLDR: Going in with the assumption that it's not an NTFS or I/O Manager bug, my SWAG is a hardware issue and points to bad RAM/thermal problem. I'd run a memory test overnight or something and see if anything pops up...

I didn't chase everything but this is what I see that made me think hardware:

Note the crash gives you the arguments to IoBuildPartialMdl:

    IoBuildPartialMdl(
        IN PMDL SourceMdl,
        IN OUT PMDL TargetMdl,
        IN PVOID VirtualAddress,
        IN ULONG Length
        )
Arguments:
Arg1: ffffc788ba2bc060
Arg2: ffffc788ba2bcaf0
Arg3: ffffc788ba673000
Arg4: 00000000ffe01000

So we can see the SourceMdl and the valid range of virtual addresses in it:

4: kd> dt nt!_mdl ffffc788ba2bc060
   +0x000 Next             : (null) 
   +0x008 Size             : 0n184
   +0x00a MdlFlags         : 0n12
   +0x00c AllocationProcessorNumber : 5
   +0x00e Reserved         : 0
   +0x010 Process          : (null) 
   +0x018 MappedSystemVa   : 0xffffc788`ba464000 Void
   +0x020 StartVa          : 0xffffc788`ba464000 Void
   +0x028 ByteCount        : 0x11000
   +0x02c ByteOffset       : 0
4: kd> ?0xffffc788`ba464000+0x11000
Evaluate expression: -62084921995264 = ffffc788`ba475000

The TargetMdl is only a page long:

4: kd> dt nt!_mdl ffffc788ba2bcaf0
   +0x000 Next             : (null) 
   +0x008 Size             : 0n176
   +0x00a MdlFlags         : 0n28
...
   +0x028 ByteCount        : 0x1000
   +0x02c ByteOffset       : 0

Now if you look at the VirtualAddress and Length passed in we have problems:

Arg3: ffffc788ba673000
Arg4: 00000000ffe01000

First, the VirtualAddress is out of range from the base of the SourceMdl and length:

4: kd> ?ffffc788ba673000-0xffffc788`ba464000
Evaluate expression: 2158592 = 00000000`0020f000

And then the Length is way out there:

4: kd> ?00000000ffe01000
Evaluate expression: 4292874240 = 00000000`ffe01000

The length looks like a DWORD underflow and the VirtualAddress could be off by a bit because if you flip bit 21 you get a more likely address and resulting length:

4: kd> ?ffffc788ba473000-0xffffc788`ba464000
Evaluate expression: 61440 = 00000000`0000f000

That itself wouldn't be conclusive, the structure these values are getting pulled from is in non-paged pool so could be a driver bug, but then there's another interesting bit if you look at processor 0:

4: kd> ~0
0: kd> k
 # Child-SP          RetAddr               Call Site
00 fffff803`760080e8 fffff803`e49b1786     nt!KeBugCheckEx
01 fffff803`760080f0 fffff803`e4ab7cd2     nt!KiFatalExceptionHandler+0x22
02 fffff803`76008130 fffff803`e46b4e67     nt!RtlpExecuteHandlerForException+0x12
03 fffff803`76008160 fffff803`e47eb132     nt!RtlDispatchException+0x347
04 fffff803`760088d0 fffff803`e4aae8f2     nt!KiDispatchException+0x372
05 fffff803`76008fb0 fffff803`e4aae8c0     nt!KxExceptionDispatchOnExceptionStack+0x12
06 fffff803`76018ae8 fffff803`e4ac283e     nt!KiExceptionDispatchOnExceptionStackContinue
07 fffff803`76018af0 fffff803`e4abd525     nt!KiExceptionDispatch+0x13e
08 fffff803`76018cd0 fffff803`e4aafff9     nt!KiGeneralProtectionFault+0x365
09 fffff803`76018e68 fffff803`e4aba29b     nt!KiSetSpecCtrlNmi+0x29
0a fffff803`76018e70 fffff803`72cb0003     nt!KiNmiInterrupt+0xdb
0b fffff803`75ff0838 fffff803`e462f76b     0xfffff803`72cb0003
0c fffff803`75ff0840 fffff803`e498a3d6     nt!HvcallInitiateHypercall+0x6b
0d fffff803`75ff08d0 fffff803`b6b4636d     nt!HvlRequestProcessorHalt+0x26
0e fffff803`75ff0900 fffff803`b6b4e1a1     amdppm!HvRequestIdle+0x2d
0f fffff803`75ff0950 fffff803`e473bc54     amdppm!LpiIdleExecute+0xb1
10 fffff803`75ff09a0 fffff803`e473a9f0     nt!PpmIdleExecuteTransition+0x518
11 fffff803`75ff0b30 fffff803`e4aaf684     nt!PoIdle+0x190
12 fffff803`75ff0c00 00000000`00000000     nt!KiIdleLoop+0x54

What happened here is that when processor 4 triggered the crash it sent processor 0 an NMI to freeze/stop. In trying to handle that NMI the OS triggered a #GP on processor 0. If you switch to the processor and disassemble that routine it reads an MSR, stores the value, then writes the MSR with contents from the PCR->PRCB. This then triggered the #GP, so must be something about the bits it doesn't like. And, interestingly, the code reads 0x82 from the MSR and then writes 0xA3:

nt!KiSetSpecCtrlNmi:
fffff803`e4aaffd0 cmp     word ptr gs:[86Ah],0
fffff803`e4aaffda je      nt!KiSetSpecCtrlNmi+0x32 (fffff803`e4ab0002)
fffff803`e4aaffdc mov     ecx,48h
fffff803`e4aaffe1 rdmsr
fffff803`e4aaffe3 mov     dword ptr [rbp+0C0h],eax
fffff803`e4aaffe9 movzx   eax,word ptr gs:[86Ah]
fffff803`e4aafff2 mov     ecx,48h
fffff803`e4aafff7 xor     edx,edx
0: kd> dd @rbp+c0 l1
fffff803`76018fb0  00000082
0: kd> r @eax
Last set context:
eax=a3

Looking at that field in the PRCB it's the BpbNmiSpecCtrl (whatever that is). And I didn't check them all but processor 0's is definitely different by a bit:

0: kd> ??@$prcb->BpbNmiSpecCtrl
unsigned short 0xa3
0: kd> ~1
1: kd> ??@$prcb->BpbNmiSpecCtrl
unsigned short 0x83
1: kd> ~2
2: kd> ??@$prcb->BpbNmiSpecCtrl
unsigned short 0x83
2: kd> ~3
3: kd> ??@$prcb->BpbNmiSpecCtrl
unsigned short 0x83
3: kd> ~4
4: kd> ??@$prcb->BpbNmiSpecCtrl
unsigned short 0x83

So, two "strange" values at once in different bits of memory so my guess is RAM/thermal.

1 Like