Skip to content

Est. 2011ยทMicrosoft Partner 7033487ยทDelivery under 3 minยทSupport 7 days a week

Your vault is empty.

License Error 0x00000019

BAD_POOL_HEADER 0x00000019 and BAD_POOL_CALLER 0x000000C2 explained

12 min read Updated October 5, 2026 Windows Crashes & Boot Recovery

Fix it now

0x00000019 means a pool header is corrupt, and 0x000000C2 means the current thread made a bad pool request. Both carry a parameter 1 subtype that says exactly which kind of mistake was found, and that value is the fastest triage available on either code.

Run these in an elevated Command Prompt to see what is loaded in the kernel

fltmc
driverquery /si /fo table
  1. Get parameter 1 from the BugCheck event in the System log or from !analyze -v on the newest dump in %SystemRoot%\Minidump.
  2. On 0x00000019, subtype 0x21 means the block was overrun by its consumer and 0x22 means an address was freed that has no tracking entry – both name the caller on the stack. Subtypes 0xD, 0xE, 0xF, 0x23, 0x24 and 0x25 mean a freed block’s header was modified afterwards, which usually means the preceding block was overrun.
  3. On 0x000000C2, subtypes 0x06 and 0x07 are double frees, 0x08 and 0x09 are allocating or freeing at an invalid IRQL, and 0x0A is freeing with the wrong pool tag.
  4. Check fltmc for filters belonging to products that are no longer installed, and remove them with the vendor’s own removal utility.
  5. Update the remaining third-party drivers, then re-run the workload that crashed.

Neither code proves the thread on the stack is guilty. Microsoft says of 0x00000019 that the pool was already corrupt at the time of the request, and that this may or may not be down to the caller.

If the machine is stable with the stack tidied and drivers current, stop here. The next section explains what the subtypes mean and how to find the writer.

Why it happens

Kernel pool allocations are laid out with a small header in front of each block recording its size, its tag and the size of the block before it, and free blocks are threaded onto lists. That metadata is what lets the allocator find and coalesce blocks, and it sits immediately next to data that drivers write to. A driver that writes a few bytes too many does not damage its own allocation – it damages the header of the block after it.

0x00000019 is the allocator noticing. Its parameter 1 subtypes read like a list of ways that can happen: the freelist is corrupt (0x3), adjacent block headers contradict each other (0x5), a header’s recorded previous size is too large (0x6), a header size is corrupt or zero (0x7, 0x8, 0x9, 0xA, 0x20), the data after a block being freed is corrupt because the consumer overran it (0x21), or an address is being freed with no tracking entry at all, because it has already been freed or was never allocated (0x22).

0x000000C2 is the other side of the same coin: rather than the metadata being wrong, the request itself is. Its subtypes cover freeing pool twice, allocating or freeing at an IRQL where that is not allowed, freeing with a tag that does not match the one used to allocate, and freeing addresses that were never allocated. Where 0x19 says the pool is damaged, 0xC2 says the caller on the stack asked for something illegal – which makes it the more directly attributable of the two.

0x00000041 gets grouped with these and should not be treated as a leak. Its published cause is that no driver is permitted to request must-succeed pool at all, and the documented fix is to replace or rewrite the driver making the request rather than to free up memory. Microsoft does allow that a second component may have depleted the pool, and gives !vm 1 and !poolused 2 for finding it – but the first reading is a driver doing something it is not allowed to do.

A driver overrunning its allocation

You have this one if 0x00000019 with parameter 1 of 0x21, or one of the freed-header subtypes, and the named module changing between crashes.

  1. Identify the pool tag from the dump with !pool on the address in the parameters.
  2. On a test machine, enable the standard Driver Verifier set – which includes special pool – against the suspect drivers.
  3. Where the tag can be seen but not attributed to a driver, use the Global Flags utility to enable special pool by pool tag instead.
  4. Once the writer is named, install its current build or remove the product.

A leftover kernel driver from a failed uninstall

You have this one if fltmc shows a filter belonging to a product that is not installed, or Device Manager with hidden devices shown lists a service nobody recognises.

  1. Use the vendor’s dedicated removal utility rather than the installed programs list.
  2. Confirm with fltmc after restarting, not with the uninstaller’s success message.
  3. Remove the driver package itself with pnputil /enum-drivers then pnputil /delete-driver <oem#.inf> /uninstall.
  4. Confirm Microsoft Defender has taken over again once the third-party product is genuinely gone.

A driver making an illegal pool request

You have this one if 0x000000C2 with parameter 1 of 0x06, 0x07, 0x08, 0x09 or 0x0A. The stack names a driver directly.

  1. Read the subtype: a double free, an allocation or free at an invalid IRQL, or a free with the wrong tag.
  2. The thread on the stack is making the request, so the driver it belongs to is the one to update or remove.
  3. Send the dump and the subtype to the vendor. These are unambiguous defects and a report with a subtype is actionable.
  4. If no fixed build exists, remove the product and confirm the crashes stop.

A driver asking for must-succeed pool

You have this one if 0x00000041 rather than 0x19 or 0xC2.

  1. Run kb in the debugger. Microsoft says it will show the driver that caused the error.
  2. That driver is at fault by definition – no driver is permitted to request must-succeed pool. Replace or remove it.
  3. If you suspect a second component depleted the pool instead, run !vm 1 for total pool usage and !poolused 2 and !poolused 4 for per-tag nonpaged and paged usage.
  4. The component behind the tag using the most pool is the likely source.

Full reference

0x00000019 parameter 1 subtypes

Value What was found
0x2 The special pool pattern check failed – the owner has likely corrupted the block
0x3 The pool freelist is corrupt; in a healthy list parameters 2, 3 and 4 are identical
0x5 Two adjacent pool entries have headers that contradict each other
0x6 The header’s previous size is too large
0x7, 0x9, 0xA, 0x20 The pool block header size is corrupt
0x8 The pool block header size is zero
0xD, 0xE, 0xF, 0x23, 0x24, 0x25 A freed block’s header was modified after it was freed, usually because the preceding block was overrun
0x21 The data after the block being freed is corrupt – the consumer overran it
0x22 An address being freed has no tracking entry: already freed, or never allocated

0x000000C2 parameter 1 subtypes worth knowing

Value The request that was made
0x06, 0x07 Freeing pool that has already been freed
0x08 Allocating pool at an invalid IRQL
0x09 Freeing pool at an invalid IRQL
0x0A Freeing pool with a tag that does not match the allocation
0x41 to 0x50 Freeing an address that was never allocated, in various forms

Finding the writer rather than the reporter

Both codes tend to fire in whichever component next touched the damaged metadata, so the module named in the dump is frequently innocent. Special pool is the tool that removes the delay: every allocation gets its own page with an inaccessible guard page after it, so an overrun faults immediately with the offender on the stack. Microsoft’s documented sequence is to walk the pool links in the debugger to get a candidate tag, then use special pool for that tag, or Driver Verifier’s special pool option against the suspect driver.

Command Purpose
!pool <address> The pool block at an address, its tag and header state
!poolused 2 Nonpaged pool usage by tag
!poolused 4 Paged pool usage by tag
!vm 1 Total pool usage
verifier /standard /driver name.sys Standard checks, including special pool, against named drivers
verifier /querysettings What is configured now
verifier /reset Clears it again, after the next boot

Driver Verifier deliberately crashes machines and Microsoft states it should be run only on computers used for testing and debugging. Enable it with verifier /bootmode resetonbootfail so a failed start clears it, and never leave it enabled on a machine in service.

0x00000021, and why it is not a counter to watch

QUOTA_UNDERFLOW means quota charges have been mishandled by returning more quota to a block than was previously charged. Parameter 1 is the process initially charged, parameter 2 the quota type, parameter 3 the amount to return, and parameter 4 the amount that was not returned. It describes an accounting error inside a component, not a system running short of anything, and there is nothing to tune in response to it.

Ruling out the cheap causes first

  • Test memory. Failing RAM imitates pool corruption closely, and Windows Memory Diagnostics with the extended test mix costs a night.
  • Check fltmc against the list of products you believe are installed.
  • Look for two real-time scanners on one machine. It is not a documented cause of these codes, but it is a pattern worth ruling out before an investigation.
  • Run sfc /scannow and, if it reports files it could not repair, DISM /Online /Cleanup-Image /RestoreHealth.
  • Compare several dumps. A stable subtype with a changing module is a corruption hunt; a stable module with subtype 0xC2 0x06 or 0x0A is a driver defect you can report today.

When a licence is the actual fix

Where the trail ends at a security agent left half-removed by a failed uninstall, or at one whose kernel components stopped updating when the licence lapsed, the fix is either full removal or a supported build – not an exclusion. Removing the product and running Microsoft Defender costs nothing, ships with Windows, and leaves one fewer filter on the stack. Where managed policy, device control and reporting across a fleet are needed, a current licence restores update delivery so the kernel driver tracks the Windows builds you are running. Arco supplies Trend Micro Worry-Free Services licences and can check which seat count and term matches your estate.

Every code this article covers

Code What it points at Source
0x00000019 BAD_POOL_HEADER: a pool header is corrupt. Microsoft states the pool was already corrupt at the time of the request and that this may or may not be down to the caller. Parameter 1 distinguishes a corrupt freelist, contradictory adjacent headers, a corrupt or zero block size, an overrun by the consumer, and an address freed with no tracking entry Microsoft Learn
0x000000C2 BAD_POOL_CALLER: the current thread is making a bad pool request. Parameter 1 subtypes cover double frees, allocating or freeing at an invalid IRQL, freeing with the wrong tag, and freeing addresses that were never allocated Microsoft Learn
0x00000041 MUST_SUCCEED_POOL_EMPTY: a kernel-mode thread requested too much must-succeed pool. No driver is permitted to request must-succeed pool at all, so the documented fix is to replace or rewrite that driver; Microsoft also allows that a second component may have depleted the pool, findable with !vm 1 and !poolused Microsoft Learn
0x00000021 QUOTA_UNDERFLOW: quota charges have been mishandled by returning more quota to a block than was previously charged. Parameter 1 is the process initially charged and parameter 4 the amount that was not returned Microsoft Learn

Confirm the fix worked

  1. fltmc lists only filters belonging to products that are installed and supported on this Windows build.
  2. verifier /querysettings reports no active verification before the machine returns to service.
  3. Windows Memory Diagnostics passes an extended run with the result recorded in the System log.
  4. The workload that crashed the machine runs to completion twice with no new dump files.
  5. If a driver was replaced, the subtype that used to appear no longer does.

Questions people ask about this

Is the driver named in the dump the guilty one?

Not necessarily. Microsoft says of 0x00000019 that the pool was already corrupt when the request was made, and that this may or may not be down to the caller. 0x000000C2 is more directly attributable, because the illegal request is being made by the thread on the stack.

What is the fastest way to triage either code?

Parameter 1. It is a specific subtype in both cases – an overrun, a double free, a wrong tag, an invalid IRQL – and it is available from the BugCheck event in the System log without opening a debugger.

Does 0x00000041 mean I need more memory?

No. Its published cause is that a driver requested must-succeed pool, which no driver is permitted to do. The documented fix is to replace or rewrite that driver. More RAM does not make an illegal request legal.

Two antivirus products are installed. Is that the cause?

It is a pattern worth removing, but Microsoft does not publish it as a cause of these codes. Take the duplication out because only one real-time scanner should own the filter path, then see whether the crashes stop – and keep investigating if they do not.

Can I fix this without a debugger?

Often. Reading parameter 1 from the System log, tidying the filter stack, updating drivers and testing memory resolves a large share of real cases. The debugger is what you need when the named module keeps changing.

Related error codes

Was this article helpful?

Your feedback helps us improve our documentation.

Related articles

Free Fix DPC_WATCHDOG_VIOLATION 0x00000133 – PC freezes then blue screens Free Fix KERNEL_DATA_INPAGE_ERROR 0x0000007A – Windows could not read from disk Free Fix ATTEMPTED_EXECUTE_OF_NOEXECUTE_MEMORY 0x000000FC and DEP blue screens Free Fix UNMOUNTABLE_BOOT_VOLUME 0x000000ED – Windows cannot mount the C: drive
โ† Back to Knowledge Base