0x00000019 BAD_POOL_HEADER

Windows found a pool header in a state that should be impossible. Microsoft's own description of the cause is unusually blunt - the pool is already corrupted at the time of the request, and this may or may not be due to the caller. That single sentence explains why chasing the driver named in the dump so often leads nowhere.

Updated 2026-07-28Stop errorAlso written: 0x19, BAD POOL HEADER, bad_pool_header

What you are looking at

:(

Your PC ran into a problem and needs to restart.

Stop code: BAD_POOL_HEADER

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: 0x00000019 (0x0000000000000003, 0xffffa50c1d2e0000, 0xffffa50c1d2e0000, 0xffffa50c1e4b2100).

What the error actually means

Every block of pool memory carries a header describing its size and state, and those headers sit immediately alongside the data they describe. That layout is efficient and fragile: a driver writing a few bytes past the end of its own allocation lands squarely on the header of the block that follows.

The pool manager validates headers on every operation. When it finds one that contradicts itself or its neighbours, it stops - because a pool with inconsistent bookkeeping will hand out overlapping allocations and corrupt unrelated data.

The crucial point is the ordering. The driver that caused the damage has usually finished and moved on. The crash happens when some later, entirely well-behaved operation touches the damaged block. Microsoft says this outright for several parameter values: the corruption is typically not the fault of the prior owner of the freed block, but of the block preceding it being overrun.

Reading the parameters

Parameter 1 is the violation type and the others change meaning with it. Several of these give you something you can check directly.

ParameterWhat it holds
0x3The pool freelist is corrupt. Parameter 2 is the pool entry being checked, parameter 3 the read-back forward link, parameter 4 the read-back backward link. In a healthy list, parameters 2, 3 and 4 are identical - so comparing them yourself tells you immediately how the list was damaged, without a debugger.
0x21The data following the pool block being freed is corrupt. Microsoft says this typically means the call stack has overrun the block - which makes this one of the few values where the code that crashed really is the code at fault. Parameter 2 is the pool pointer, parameter 3 the bytes allocated, parameter 4 the corrupted value found after the block.
0x22An address being freed has no tracking entry - the call stack is trying to free a pointer that was already freed, or was never allocated. A double free or a wild pointer. Parameter 2 is the address.
0xD, 0xE, 0xF, 0x23, 0x24, 0x25The pool header of an already-freed block was modified after it was freed. Microsoft's note here is the important one: this is not typically the fault of the prior owner of that block, but usually of the block preceding it being overrun. All parameters reserved.
0x5A pair of adjacent pool entries have headers that contradict each other, and at least one is corrupt. Parameters 2 and 4 hold the two entries.
0x2The special pool pattern check failed - the owner has likely corrupted the pool block. You will normally only see this with Driver Verifier's Special Pool enabled, which is the point of enabling it.
0x6 / 0x9The pool block header's previous size, or its size, is too large. Parameter 2 is the incorrectly calculated entry, parameter 4 the bad entry that caused the miscalculation.
0x7 / 0x8 / 0xA / 0x20The pool block header size is corrupt, or zero. Parameter 4 usually holds the bad pool entry.

What actually triggers it

A driver mishandling memory, with hardware as the alternative when no driver can be pinned down.

CauseHow oftenDetail
A driver overrunning its allocationCommonThe classic case, and the reason the named module is so often innocent. A driver writes past the end of its own block and damages the header of the next one; the crash surfaces when something else touches that neighbour.
Anti-virus and filter driversCommonThese allocate and free pool constantly while inspecting file and network activity. A version mismatch after a Windows update produces header corruption reliably.
A double free or wild pointerOccasionalParameter 1 of 0x22 indicates this specifically - a driver freeing something twice, or freeing a pointer that was never a pool allocation.
Failing RAMOccasionalMicrosoft's resolution section says directly that if this bugcheck appears inconsistently, it could be related to faulty physical memory. A flipped bit in a header looks identical to a driver overrun from the pool manager's point of view.
Unstable memory settingsOccasionalAn XMP or EXPO profile beyond what the memory controller sustains produces intermittent corruption with exactly this signature.

Narrowing it down

Read the violation type first - it decides whether the crashing code is a suspect or a bystander.

Check parameter 1 and classify

Pull the full parameter set from the bugcheck event:

Get-WinEvent -FilterHashtable @{LogName='System'; Id=1001} |
  Where-Object { $_.Message -match '0x00000019' } |
  Select-Object TimeCreated, Message |
  Format-List
What it tells you

0x21 and 0x22 implicate the crashing call stack directly - the driver in the dump is a real suspect. 0xD, 0xE, 0xF, 0x23, 0x24, 0x25 explicitly do not - the damage came from a neighbouring block, and the named driver is a bystander.

On 0x3, compare parameters 2, 3 and 4

Microsoft states that in a healthy freelist those three values are identical. Read them straight off the bugcheck message.

What it tells you

Which one differs, and by how much, characterises the damage. A value differing from the other two by a single bit is a strong hint at memory rather than a driver - that is what a bit flip looks like. A wildly different value looks more like something overwrote the pointer.

Check whether the named module is consistent

Open several dumps and compare MODULE_NAME. Microsoft warns that !analyze is frequently unhelpful at pinpointing the suspect driver with pool corrupters.

What it tells you

Different modules each time is expected on this bugcheck and does not by itself mean hardware. It means the corruption is landing in different places - which is why Driver Verifier rather than dump reading is the tool that resolves this.

Note whether it is consistent or sporadic

Does it happen predictably under certain activity, or at random intervals with no pattern?

What it tells you

Microsoft's guidance ties inconsistent appearances to faulty physical memory. A reproducible pattern tied to specific software points at a driver; genuinely random occurrences move memory up the list.

Fixes, cheapest first

Microsoft's stated resolution is Special Pool on the suspect driver. That is the right answer and it is worth reaching for early.

  1. Run Driver Verifier with Special Pool

    Effort: Several hours · Risk: Medium

    Special Pool positions each allocation so that writing past its end faults immediately, in the driver that did it, rather than damaging a neighbour and surfacing later. That converts this bugcheck from unidentifiable to identifiable, which is precisely the problem it presents.

    Full settings and the boot-fail safety flag are in the Driver Verifier guide.

    Watch out

    Verifier deliberately increases crashes and can cause a boot loop. Run verifier /bootmode resetonbootfail before 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 by verifier /reset. Full settings and the escape route are in the Driver Verifier guide.

  2. Remove third-party security software

    Effort: 20 minutes · Risk: Low

    Uninstall third-party anti-virus and run on Windows Defender for a few days. Use the vendor's dedicated removal tool rather than the standard uninstaller - these products routinely leave kernel drivers behind.

  3. Test the memory

    Effort: Overnight · Risk: None

    Particularly if the crashes are sporadic rather than reproducible. Disable XMP or EXPO first, then run MemTest86 from USB for at least four passes. See the memory testing guide - the built-in Windows tool is not sensitive enough to trust a pass from.

  4. Return memory settings to stock

    Effort: 10 minutes · Risk: Low

    Disable XMP, EXPO and any manual timings, and run for several days. If the crashes stop, the profile was not achievable on your combination of parts - the modules are probably fine.

  5. Strip back kernel-level software

    Effort: 30 minutes · Risk: Low

    Uninstall anything that installs a kernel driver and is not essential: RGB and fan utilities, VPN clients, virtual drive software, old printer packages, anti-cheat services from games you no longer play. Then run a clean boot for a day.

When it is the hardware, not Windows

Signals that memory rather than a driver is doing the corrupting:

The single-bit test on parameter 1 = 0x3 is worth knowing. Software errors tend to write plausible-looking garbage or zero; a value that differs from its neighbours in exactly one bit position is what a memory fault looks like, and it is checkable from the blue screen message alone.

Frequently asked

How is this different from BAD_POOL_CALLER?

Timing. 0xC2 BAD_POOL_CALLER means the current request was invalid - the caller did something wrong right now. 0x19 BAD_POOL_HEADER means the pool was already corrupted when the request arrived. That is why the caller is a suspect on 0xC2 and usually a bystander on 0x19. The fix converges anyway: Driver Verifier with Special Pool, then memory testing.

The dump names a Microsoft driver. Does that mean Windows is broken?

No. Microsoft components allocate and free pool constantly, so they are statistically likely to be the ones that touch a damaged block first. Microsoft's own documentation warns that !analyze frequently cannot pinpoint the suspect driver with pool corrupters. Treat the name as where the damage was found, not where it was made.

Why does this seem to happen randomly?

Because the crash depends on which block gets touched after being damaged, and that varies with whatever the machine happens to be doing. The same underlying overrun can crash in a different component, at a different time, on every occurrence. Microsoft ties genuinely random appearances to faulty physical memory - but a driver overrun also produces apparent randomness, which is why Verifier exists.

Can I just reinstall Windows?

It helps if the cause is a badly installed or conflicting driver, which is a fair share of cases. It does nothing for failing memory or an unstable memory profile - and since Microsoft explicitly links sporadic occurrences of this bugcheck to faulty physical memory, testing the RAM before reinstalling is worth the overnight run. A reinstall also destroys the crash history you would need if this turns out to be hardware.