RAM problems do not look like RAM problems
A home server with a failing memory module rarely announces itself with a blue screen and a memory code. On a Windows mini PC running Docker, the symptoms arrive disguised as other failures: a WSL2 backend that dies mid-afternoon, containers that restart for no visible reason, file copies that hang at the same awkward size, or a server that reboots overnight and comes back with half the services unhealthy. Each of those has a more mundane explanation, which is exactly why memory testing keeps getting postponed.
The cheapest way to close that question is the tool Windows already ships with: Windows Memory Diagnostic (mdsched.exe). The catch is that the tool is designed for a desktop user sitting in front of the screen. On a home server, the blue full-screen test runs before Windows boots, and if you are not watching, the only trace of the run is in the event log. This guide covers both halves of that workflow: scheduling the test unattended, and reading the actual verdict afterward — with the numbers from a real run on our 16 GB Beelink EQI12 test unit rather than generic instructions.
What the tool actually tests
Windows Memory Diagnostic runs before the operating system loads, so it can test the memory Windows itself occupies. Two modes are offered:
| Mode | What it does | When to choose it |
|---|---|---|
| Standard | Basic test passes over all reachable memory | First check, routine verification |
| Extended | Adds cache and pass patterns, takes considerably longer | Standard passed but symptoms persist |
Choose the mode on the blue screen with F1, or accept the default. For an unattended server run, the standard test is the practical choice: it completes in minutes rather than hours, and its verdict is stored in exactly the same place.
One thing the tool does not do: it is not MemTest86. MemTest86 boots from USB and runs its own environment with more aggressive patterns and support for multiple loop passes overnight. Start with the Windows tool because it is free, built in, and schedulable; move to MemTest86 when you need repeated overnight passes or a second opinion before RMA.
Scheduling the run on a headless server
The graphical wizard schedules the same thing you can do from an elevated prompt, and the scriptable path is more useful on a server. Windows Memory Diagnostic lives in a boot entry called {memdiag}. You can push it to the front of the next boot sequence with bcdedit:
bcdedit /bootsequence {memdiag}
shutdown /r /t 20 /c "Windows Memory Diagnostic"/bootsequence is the key detail. It inserts {memdiag} as a one-time first boot entry — after the diagnostic completes and reboots, the machine returns to the normal boot order with nothing else to clean up. That is different from /displayorder, which would permanently reorder the boot menu, and it is the reason this method is safe to run remotely: even if the diagnostic fails to complete, the next boot proceeds normally.
This is exactly how we scheduled our run on the EQI12 test unit. Our scheduling script logged the bcdedit output and exit code before issuing the restart, which we recommend as a habit: the two lines of log are what let you prove, weeks later, that the test was actually queued rather than silently skipped. The full capture script is published alongside the raw evidence in the eqi12-measurement-data repository, memory/ directory.
After the restart command goes out, the server drops to the blue diagnostic screen, runs the test, and boots back into Windows on its own. Nobody needs to be present.
Where the verdict lives: Event IDs 1101 and 1201
The result is not flashed on screen for five seconds and lost. After the post-diagnostic boot, Windows writes the outcome to the System event log from the provider Microsoft-Windows-MemoryDiagnostics-Results, and you can read it over RDP, SSH, or any remote management console you already use for the server.
Two event IDs matter:
| Event ID | Content | Use it for |
|---|---|---|
| 1101 | Detailed result with a full XML payload | The authoritative verdict and coverage numbers |
| 1201 | Short human-readable summary | Quick confirmation, alerting rules |
Pull both with PowerShell on the server:
Get-WinEvent -FilterHashtable @{
LogName = 'System'
ProviderName = 'Microsoft-Windows-MemoryDiagnostics-Results'
} | Format-List TimeCreated, Id, MessageFor the machine-readable verdict, ask for the 1101 event’s XML payload directly:
$x = (Get-WinEvent -FilterHashtable @{
LogName = 'System'
ProviderName = 'Microsoft-Windows-MemoryDiagnostics-Results'
Id = 1101
} | Select-Object -First 1).ToXml()
$xIn the Event Viewer GUI you can also browse to Event Viewer → Windows Logs → System → Filter Current Log → event IDs 1101, 1201 — same data, friendlier for a one-off check.
A real measured run: the numbers
Here is the complete 1101 payload from our EQI12 run (standard test, 16 GB configuration), recorded on 2026-07-13/14. Every field below is quoted from the actual event XML stored in the data repository — this is what a healthy pass looks like, not a mock-up:
| XML field | Value | What it means |
|---|---|---|
CompletionType | Pass | The verdict. Fail means at least one bad page was found |
MemorySize | 16147 MB | Memory visible to the diagnostic (≈15.8 GiB of the 16 GB module) |
TestType | 10 | Standard test profile |
TestDuration | 1074 s | ≈ 18 minutes of actual testing |
TestCount | 12 | Test passes executed |
NumPagesTested | 4,104,471 | 4 KiB pages exercised (≈ 15.65 GiB) |
NumPagesUnTested | 2,363 | ≈ 9.2 MiB skipped (≈ 0.06 % of memory) |
NumBadPages | 0 | No faulty pages detected |
LaunchType | Unknown | How the run was initiated (scheduled, not watched) |
The per-test counters T1NumBadPages through T16NumBadPages were all zero as well. Two details in this payload are worth internalizing because they change how you read your own results:
- The pass is not 100 percent coverage. 2,363 of 4,106,834 total pages went untested. That residual is normal — firmware-reserved regions and pages claimed at boot can be unreachable — but it is why a single Windows pass does not outrank an overnight MemTest86 run when you are chasing an intermittent fault.
TestDurationis measured test time, not wall-clock. Our test logged 1074 seconds of diagnostic activity; add the reboot and boot time on either side when planning a maintenance window. The whole unattended cycle — restart, test, reboot back into Windows — fit comfortably inside half an hour.
What we did next: verify the server came back whole
A memory test on a home server is not just a verdict — it is also an unplanned power cycle of a machine that normally runs for weeks. That makes the post-diagnostic boot a bonus recovery drill. Our capture script recorded what came back after the run:
- Post-diagnostic boot: 2026-07-13 23:35:54 local time; result events 1101 and 1201 written at 23:36:22, seconds after login.
- Docker stack: all four containers (
jellyfin,test-database,test-web,test-cache) reported Up 3 minutes (healthy) immediately after the boot. - Verdict: PASS — no memory errors.
That last line is the operational payoff of running diagnostics deliberately: you get a fresh proof that the stack survives a full restart unattended. If your containers do not come back this cleanly, the problem is not memory — it is your restart dependencies, which is what our Docker containers not starting after reboot walkthrough is for. And for the longer view of machine health, this diagnostic pairs naturally with the 12-hour stability soak test we ran on the same unit: the soak test finds load-dependent instability, the memory diagnostic rules out the hardware underneath it.
Reading a failure: what NumBadPages tells you
If CompletionType comes back Fail, do not rush to pull the module. Read the payload in order:
NumBadPagesis small (single digits to low hundreds). Note the count, re-run the standard test once. Transient single-bit errors can come from marginal power or interference rather than a dead cell; a repeatable count that grows between runs is the signature of real hardware damage.- Bad pages cluster in one test (
T7but not others, say). Pattern information is thin in the Windows tool, but consistency across runs matters more than the pattern itself. - The verdict is per-system, not per-stick. Windows Memory Diagnostic does not tell you which module owns the bad pages. With more than one SO-DIMM installed, test with one module at a time, or run MemTest86 which displays failing addresses you can map to slots.
- Confirm before RMA with the vendor. Screenshot or export the 1101 event XML — it is timestamped, machine-readable evidence of the failure, and it beats describing “it crashed sometimes” to a support desk.
Where this fits in a maintenance routine
For a Windows mini PC home server, a sensible cadence is: schedule the standard diagnostic whenever you open the machine (firmware update, new stick, hardware change), after any unexplained reboot cluster, and — if nothing forces your hand — as part of a quarterly maintenance window alongside checking drive health with smartctl or our SMART NVMe health tool. The 1101 event payload gives you a comparable number (pages tested, bad pages) to file next to your SMART snapshots, which turns “the machine seems fine” into a recordable fact.
The complete raw evidence for the run documented here — the scheduling log, the CSV of result events, the full XML payloads, and the post-diagnostic container status — is published under CC BY 4.0 in the eqi12-measurement-data repository together with the rest of our EQI12 test measurements.
If your restart recovery did not go as smoothly as ours, start with getting containers to start after reboot; if you are still deciding what this kind of mini PC can carry, the home server stack reference shows the workload this 16 GB unit runs.