0x00000139 KERNEL_SECURITY_CHECK_FAILURE
This is not a crash in the usual sense. The kernel validates critical data structures as it uses them, and when a check fails it stops the machine immediately and deliberately - because continuing with corrupted kernel data is how a bug becomes a security compromise. The parameter that matters tells you what kind of corruption was found, and that narrows the field considerably.
What you are looking at
Your PC ran into a problem and needs to restart.
Stop code: KERNEL_SECURITY_CHECK_FAILURE
In Event Viewer the matching entries look like this:
Log Name: System
Source: BugCheck
Event ID: 1001
Level: Error
The computer has rebooted from a bugcheck. The bugcheck was: 0x00000139 (0x0000000000000003, 0xffffb80f2c1a4530, 0xffffb80f2c1a4488, 0x0000000000000000).
What the error actually means
Modern Windows kernels are built with integrity checks compiled in. Stack cookies detect buffer overruns before a function returns. Linked list operations verify that a node's neighbours actually point back at it. Control-flow guards check that an indirect call is going somewhere legitimate.
These checks exist because kernel memory corruption is not merely a stability problem - it is the mechanism behind privilege escalation exploits. So when a check fails, the kernel does not attempt to recover or continue in a degraded state. It halts immediately, on the principle that a stopped machine is safer than a compromised one.
The critical implication for diagnosis: this bugcheck reports detection, not causation. The code that was running when the check failed is frequently the victim - it read a structure someone else had already damaged. The driver named in the dump may be entirely innocent.
Reading the parameters
Parameter 1 identifies which check failed, and it is the most informative value on this page. One thing to watch: Microsoft documents these values in decimal, not hex, which is unusual - almost everything else about bugchecks is hexadecimal. A parameter 1 of 10 means ten, not sixteen. Around thirty values are defined; these are the ones that turn up in practice.
| Parameter | What it holds |
|---|---|
| 0 | A stack-based buffer was overrun - the legacy /GS violation. Something wrote past the end of a local buffer. |
| 1 | VTGuard detected an attempt to use an illegal virtual function table. Typically a C++ object was corrupted and a virtual method call then used the corrupted object's pointer. |
| 2 | Stack cookie instrumentation detected a stack-based buffer overrun - the modern /GS violation. Same class of fault as value 0, caught by newer instrumentation. |
| 3 | A LIST_ENTRY is corrupted - for example, the same entry removed twice. The most common value by a wide margin, and the one the Cause section below is written for. |
| 5 | An invalid parameter was passed to a function that treats invalid parameters as fatal. |
| 8 | A compiler-inserted array bounds check caught an illegal array indexing operation. |
| 10 | Indirect call guard detected an invalid control transfer - Control Flow Guard catching a call heading somewhere it should not. |
| 11 | Write guard detected an invalid memory write. |
| 14 | The reference count for an object is invalid. Usually means an object was released more times than it was referenced. |
| 29 | An RTL_BALANCED_NODE red-black tree entry is corrupted - the tree equivalent of the LIST_ENTRY case. |
| 2 / 3 / 4 | Parameter 2 is the address of the trap frame for the exception, parameter 3 the address of the exception record. Both are for debugger use. Parameter 4 is reserved. |
What actually triggers it
Because the check catches corruption rather than causing it, the underlying cause list is broad - but the distribution still favours drivers.
| Cause | How often | Detail |
|---|---|---|
| Driver bugs | Common | Overrunning a buffer, mishandling a linked list, or using an object after freeing it. Storage, network and security drivers are frequent sources because they manipulate lists heavily. |
| Anti-virus and filter drivers | Common | Security products insert themselves into kernel data structures by design, and a version mismatch after a Windows update produces list corruption reliably. |
| Failing RAM | Occasional | A flipped bit in a list pointer is exactly what the LIST_ENTRY check is looking for. The check fires correctly; the corruption came from hardware. |
| Unstable memory or CPU settings | Occasional | An XMP profile beyond what the controller can sustain, or an unstable overclock or undervolt, corrupts data in transit. This produces the same signature as failing memory. |
| Corrupt system files | Rare | Possible where a system binary itself is damaged, but not a leading explanation. |
| Malware | Rare | Worth mentioning because these checks were designed partly to catch exploitation. A rootkit manipulating kernel structures can trigger them - though a buggy driver is far more likely. |
Narrowing it down
Read parameter 1 first, then decide whether you are chasing a driver or chasing memory.
Record parameter 1 across several crashes
Pull the bugcheck records so you have the full parameter set for each:
Get-WinEvent -FilterHashtable @{LogName='System'; Id=1001} |
Where-Object { $_.Message -match '0x00000139' } |
Select-Object TimeCreated, Message |
Format-List
A consistent parameter 1 - especially 0x3 - with a consistent module named in the dump is a specific driver bug. Values that vary between crashes suggest general memory corruption rather than one broken routine.
Check whether the named module is stable across crashes
Open several dumps in WinDbg and compare MODULE_NAME from !analyze -v.
Same module every time points at that driver. A different module each time is the signature of memory corruption, and it is the single most useful thing this bugcheck can tell you - because it decides whether you spend the next week on drivers or on RAM.
Test memory before committing to a driver hunt
Disable XMP or EXPO, then run MemTest86 from USB for at least four passes.
A clean run at stock settings lets you pursue drivers with confidence. Errors end the investigation immediately, and everything above becomes irrelevant.
Fixes, cheapest first
Which branch you take depends on the triage above - a stable module means drivers, a shifting module means memory.
Remove third-party security software
Given how often this involves filter drivers, uninstall third-party anti-virus first and run on Windows Defender alone for a few days. Use the vendor's dedicated removal tool rather than the standard uninstaller - these products routinely leave drivers behind.
Update the named driver
If dumps consistently name one module, get its current version from the hardware vendor directly. If the crashes started after a driver update, install the previous release instead.
Remember the caveat: on this bugcheck the named module is frequently a victim rather than the culprit. If updating it changes nothing, do not conclude the driver was fine - conclude that the corruption is coming from elsewhere.
Return memory and CPU to stock
Disable XMP, EXPO, any manual memory tuning, and any CPU overclock or undervolt. Curve optimiser settings on Ryzen and undervolts on Intel are common causes of corruption that looks exactly like a driver bug.
Run at stock for several days before drawing conclusions.
Test memory thoroughly
MemTest86 from USB, minimum four passes, at stock settings. If errors appear, test each module individually in the same slot to identify which one.
Verify system files
Cheap to rule out.
sfc /scannowDISM /Online /Cleanup-Image /RestoreHealthsfc /scannowagain
Run Driver Verifier
Verifier is well suited to this bugcheck because Special Pool catches buffer overruns at the moment they happen, rather than when a later check notices the damage. That converts an unhelpful dump naming a random module into one naming the actual offender.
- Create a restore point and confirm you can reach Safe Mode.
- Run
verifier, choose custom settings, enable Special Pool, Pool Tracking and Force IRQL checking. - Select non-Microsoft drivers only.
- Use the machine until it bugchecks, then read the dump.
- Run
verifier /resetand reboot.
Watch outVerifier deliberately increases crashes and can cause a boot loop. Run
verifier /bootmode resetonbootfailbefore enabling any checks - it makes Verifier disable itself automatically if the machine fails to start, which removes most of the risk. Your manual exit is Safe Mode followed byverifier /reset. Full settings and the escape route are in the Driver Verifier guide.
When it is the hardware, not Windows
Signals that memory or CPU hardware is corrupting data rather than a driver mishandling it:
- The module named in the dump differs between crashes.
- Parameter 1 varies rather than staying consistent.
- MemTest86 reports errors at stock settings.
- Other stop codes -
0x1A,0x50,0x3B- appear in the same period. - Crashes continue after a clean Windows install with minimal drivers.
- The machine is running an overclock, undervolt or memory profile above stock.
The overclock item deserves more weight than people give it. An undervolt that passes hours of benchmarking can still be unstable at the light, bursty loads of ordinary desktop use, and the corruption it produces surfaces precisely as a failed integrity check. If the machine is tuned at all, returning it to stock is not a formality - it is the test.
Frequently asked
Does this mean I have a virus?
Almost certainly not, despite the name. The word 'security' here refers to the kernel's internal integrity checks - mechanisms built to make memory corruption fail safely rather than become exploitable. They fire far more often for buggy drivers and bad RAM than for anything malicious. A scan is reasonable diligence, but do not let the name redirect the investigation.
The dump names a driver. Is that definitely the faulty one?
Less reliably than on most bugchecks. The check fires when corrupted data is used, which can be a long way from where it was damaged. If updating the named driver changes nothing, that is informative rather than disappointing - it means you are looking at the victim. Driver Verifier's Special Pool exists to close that gap by faulting at the moment of the overrun.
What does parameter 1 = 3 mean in practice?
LIST_ENTRY corruption. Windows keeps many things in doubly-linked lists, where each node points forward and backward. When an entry is added or removed the kernel verifies the neighbours agree, and value 3 means they did not.
Microsoft lists the specific driver mistakes that produce it: removing the same entry twice without reinserting it between the two removals; freeing a structure that contains a LIST_ENTRY without first taking it off its list; using a list concurrently from several threads without proper synchronisation; and corrupting a kernel synchronisation object such as a KEVENT or a periodic KTIMER, which are themselves held in lists.
The important caveat is timing: the inconsistency is detected when the list is next walked, which can be long after the damage was done. That is why the named module is so often innocent, and why Driver Verifier with Special Pool is the tool that actually finds these - it faults at the moment of the overrun rather than when someone later notices.
Why does Windows crash instead of just recovering?
Because it cannot know how far the damage extends. Corrupted kernel structures are the foundation of privilege escalation attacks, and continuing risks writing user data into unpredictable places or executing attacker-controlled code. Stopping is the deliberate, safer choice - the bugcheck is the mitigation working, not failing.
Related errors
- 0x00000050PAGE_FAULT_IN_NONPAGED_AREAMemory that could never be paged out was missing anyway. Points harder at RAM than most codes.
- 0x0000001AMEMORY_MANAGEMENTWindows' memory bookkeeping is corrupt. The first parameter tells you which kind, and that changes everything.
- 0x0000003BSYSTEM_SERVICE_EXCEPTIONA kernel fault during a system call. Usually a driver, sometimes memory, occasionally a dying board.