Forge & NeoForge · 1.16 – 1.21 · dedicated servers
Command-line tools for people who run modded Minecraft servers. One file each, no dependencies, Python 3.8+.
$ python forge_doctor.py crash-reports/crash-2026-10-01_12.34.56-server.txt Minecraft 1.20.1 Loader 47.4.10 Java 21.0.10 Reached 'Done' no Crash description: Ticking entity CULPRIT (first non-vanilla frame): grimfauna-1.20.1-2.1.11.jar in StalkerOnEntityTickUpdateProcedure [1] FATAL A mod crashed while ticking an entity or block How to fix it: update that mod, or remove the entity — the crash report gives you its coordinates.
Three jobs. One finds out why your server died. One finds the things that are broken and never say so. One keeps it running without looping on the same failure.
Reads a crash report or latest.log and reports the root cause, the mod responsible, and the fix.
--json and real exit codes for start scriptsIndexes every ID your mods actually register, then checks everything your datapacks, KubeJS scripts, quests and configs reference against it.
Restarts your crashed server, but refuses to restart into a crash it has already seen. One bad mod stops being an all-night loop.
watch mode that changes nothingPack Doctor was built against two live servers, 92 and 233 jars. These three are live right now in a pack thousands of people play. Every one was confirmed against the mod's own jar: the correct ID exists, the referenced one doesn't.
| The pack references | What actually exists | Result |
|---|---|---|
cooked_caned_fish | cooked_canned_fish | no diet category, silently |
cooked_canned_rabit_soup | cooked_canned_rabbit_soup | no diet category, silently |
stampler | stapler | removal never applies |
None of those crash. None log an error. You find out when a player complains three weeks later, if ever.
The first version of Forge Server Doctor passed every test I wrote and still missed five of eight real crash reports — the same person had written both the samples and the patterns. It got rebuilt against an actual crash-report folder.
Pack Doctor went the same way: its first run reported 169 typos on a real pack and most were noise, because comparing whole IDs lets a shared namespace inflate every similarity score. Comparing the paths alone cut it to 63 real candidates.
Both tools ship their test suites. Every test is mutation-checked — the fix reverted, the test confirmed failing — so a passing suite means something.
A long write-up of the debugging: a tool that passed every test I wrote and still misdiagnosed five of eight real crashes, a filename with two versions in it, and a performance theory that moved the number by 0.00 seconds.
Your test fixtures are lying to you: what 13 real Minecraft crash reports taught me
A diagnostic tool that overstates its reach wastes more of your time than one that admits its edges.
hs_err_pid file instead.