When a Windows Server stops responding or reboots itself, the fastest route to a root cause is a kernel memory dump plus the WinDbg !analyze -v extension. This guide is a working procedure: reproduce the crash under Driver Verifier, capture the dump reliably, load it with the correct symbol path, and read the bug check parameters without guessing. It assumes the server is a VPS or a small on-prem box where you cannot attach a kernel debugger to the physical serial port — everything here works from a dump file alone. If your instance has a small system disk, note that crash dumps are written to the page file’s backing volume, and Windows Server instance sizing matters for whether a full or kernel dump is practical.
Step 1: Choose the Dump Type Before the Crash
Crash dump configuration is a registry/BCD setting, not a control-panel tweak that applies after the fact. Decide before you run Driver Verifier.
| Type | Size | Contents | Use when |
|---|---|---|---|
| Small (minidump) | ~256 KB – 2 MB | Bug check code, parameters, current thread, loaded module list, stack of the crashing thread | Always enabled as a baseline; enough for most third-party driver faults |
| Kernel | Typically 400 MB – 2 GB | All kernel-mode memory: pools, driver images, stacks of all threads | Pool corruption, deadlocks, need driver data of a non-crashing thread |
| Complete | RAM size or larger | Entire physical memory including user mode | Rarely needed server-side; requires page file ≥ RAM |
| Automatic | Kernel by default | Kernel dump, minidump if kernel cannot be written | Good default for production |
Set it with wmic-free commands on Server 2022/2025:
# Show current setting (1=complete, 2=kernel, 3=small, 7=automatic)
Get-ItemProperty 'HKLM:\SYSTEM\CurrentControlSet\Control\CrashControl' |
Select-Object CrashDumpEnabled, DumpFile, MinidumpDir, AutoReboot, Overwrite
# Set kernel dump explicitly
Set-ItemProperty 'HKLM:\SYSTEM\CurrentControlSet\Control\CrashControl' -Name CrashDumpEnabled -Value 2
Set-ItemProperty 'HKLM:\SYSTEM\CurrentControlSet\Control\CrashControl' -Name Overwrite -Value 0
# Page file must be at least on the same disk and large enough
Get-CimInstance Win32_PageFileUsage | Select-Object Name, AllocatedBaseSize, CurrentUsage
Overwrite=0 keeps a dump at C:\Windows\MEMORY.DMP instead of overwriting it on the next crash — essential when you need several runs to identify an intermittent driver. Ensure the disk has free space equal to the expected dump size before enabling a kernel dump on a 40 GB VPS disk.
Step 2: Driver Verifier — Targeted, Not “Verify Everything”
Driver Verifier’s /standard suite applied to all drivers will make a production server unbootable. On a VPS this means a recovery console session. Verify only the drivers you suspect, and only with a non-destructive option set.
# List third-party drivers and their vendors
Get-CimInstance Win32_SystemDriver | Where-Object State -eq 'Running' |
ForEach-Object {
$p = (Get-Item $_.PathName -ErrorAction SilentlyContinue).VersionInfo
[pscustomobject]@{Name=$_.Name; Company=$p.CompanyName; File=$_.PathName}
} | Where-Object Company -notlike 'Microsoft*' | Format-Table -AutoSize
Pick one driver and enable only the options that are meaningful for it:
verifier /volatile /adddriver myfilter.sys /flags 0x209BB
verifier /volatile /querysettings
The /volatile switch applies the settings until the next reboot without persisting them in the registry. That matters: if the box fails to boot under verification, a reset node in a VPS panel has already cleared the setting. Reboot, reproduce the load, and wait for bug check 0xC4 (DRIVER_VERIFIER_DETECTED_VIOLATION) — the dump now names the driver in the bug check parameters.
0x209BBis the standard suite subset most useful for filter drivers: special pool, pool tracking, I/O verification, deadlock detection, IRP logging.- Avoid
/flags 0x1(special pool) alone on file system filter drivers unless you have spare RAM — special pool is allocation-heavy and will mask timing issues with memory pressure. - Never use
verifier /flags 0x9(low resource simulation) on a server hosting production work.
Step 3: Retrieve the Dump and Symbols
- Minidumps land in
%SystemRoot%\Minidump\*.dmp; kernel dumps at%SystemRoot%\MEMORY.DMP. - Copy the dump off the server before analyzing — WinDbg’s symbol download and the analyzer’s working set can consume gigabytes.
- Use WinDbg (Store app “WinDbg” is the modern version; the classic
windbg.exefrom the Windows SDK still works and is faster to script). - Set the symbol path to the Microsoft symbol server plus your own cache:
set _NT_SYMBOL_PATH=srv*C:\symbols*https://msdl.microsoft.com/download/symbols
windbg.exe -z C:\dumps\MEMORY.DMP -c ".symfix; .reload /f; !analyze -v; q"
The .reload /f forces a full load of symbols; without it, !analyze may report module names with no line information and the stack will be unreadable. If you are behind a proxy, _NT_SYMBOL_PATH supports srv*https://... only after you set WinHTTP proxy settings with netsh winhttp set proxy.
Step 4: Reading !analyze -v Output
The output has five fields that matter, in order:
- BUGCHECK_CODE / BUGCHECK_P1..P4 — the stop code and its arguments. Look the code up in the official bug check reference before interpreting the parameters, because parameter meaning is code-specific.
- FAULTING_MODULE or IMAGE_NAME — the module blamed by the stack walker. This is the strongest hint, not proof.
- PROCESS_NAME — the process whose thread crashed.
Systemmeans a kernel-mode fault not tied to user code. - STACK_TEXT — the call stack. Read bottom-up. The frame that calls into a Microsoft module from a third-party module is the suspect boundary.
- FAILURE_BUCKET_ID — a stable hash of code + module + offsets. Search this string; if others report the same bucket, you have a known driver defect rather than a unique configuration issue.
Common misreads:
- A stack that ends in
nt!KeBugCheckExand nothing else with a high faulting module offset often means pool corruption — the crashing thread is the victim, not the cause. Enable special pool and rerun to find the corruptor. 0x50 PAGE_FAULT_IN_NONPAGED_AREAwith a parameter pointing insidentis frequently a stale or wrong driver calling a freed allocation;!poolon the address in the newer WinDbg shows the owning tag.0x133 DPC_WATCHDOG_VIOLATIONon a VPS is often a storage driver holding a DPC too long under high IOPS (boot storms, antivirus scans) rather than a code defect. Check the DPC time and the IO queue depths.
Step 5: Confirm with the Driver, Not the Stack
Before filing a bug, gather proof the driver is involved:
- Identify the driver’s file version from the dump’s module list (
lmvmin WinDbg prints timestamp, version, and company). - Check whether the version predates the OS build. An inbox-era driver on a Server 2025 kernel is a strong candidate.
- Rerun the workload with the driver’s feature disabled (its own registry switch) and confirm the crash disappears.
- Test on a clean VM with the same driver version and the same storage stack — this distinguishes a driver bug from a host hypervisor issue, which on a VPS is the customer’s most common false trail.
Then remove verification: verifier /volatile /reset and reboot, or verifier /reset if settings were persisted. Leaving a driver under verification in production is a scheduled outage.
Practical Notes for VPS Hosts
Two host-level details affect crash analysis. First, many providers expose a console that shows the bug check text but does not forward the dump automatically — you must pull MEMORY.DMP over RDP or SMB before any repair reinstall wipes it. Second, a provider-level reset during a hang produces event log entries (Kernel-Power 41) with no dump at all; that is a host-side action, not a bug check, and Driver Verifier will not help. Keep a copy of dumps, Get-WinEvent output, and the loaded driver list together, as described in the operations guides on Windows VPS server operations, so the next incident starts with evidence instead of a fresh install.


