Running Minecraft Java on a current version with an actively-maintained superhero-themed modpack, as a companion to an older server frozen on a legacy Forge modpack that can never be updated (see that guide for why, and the Bedrock guide if you're running both editions). Fabric on 1.20.1 turned out to need real dependency-resolution work, and produced one crash with two completely unrelated causes that happened to share the exact same error string.
A legacy Forge modpack frozen on Minecraft 1.7.10 has no upgrade path — the mod that makes it worth running was never ported past that version, confirmed directly against the mod's own CurseForge and Modrinth project pages (third-party mod-listing sites can and do claim broader version support than is actually true). Rather than lose the theme entirely, this is a from-scratch build on a current version with the closest actively- maintained equivalent instead of an attempted in-place upgrade.
This server's LXC was deliberately built on NFS-backed storage over a fast wired link to a NAS, rather than the same local ZFS pool other VMs and containers on the same hypervisor share. The reason wasn't theoretical: heavy sustained writes from an unrelated large-file export job on another VM sharing that local pool had, the same night, caused enough I/O contention to crash a completely different game server also sharing it — kicked connected players with a generic "server down" error even though the process itself never restarted.
Runs on the itzg/minecraft-server Docker image, no special Java-version pinning needed — 1.20.1
requires Java 17+ anyway, which the image's default tag already bundles:
services:
mc:
image: itzg/minecraft-server
container_name: mc-modern
ports:
- "25565:25565"
environment:
EULA: "TRUE"
TYPE: "FABRIC"
VERSION: "1.20.1"
MEMORY: "4G"
volumes:
- ./data:/data
restart: unless-stopped
stdin_open: true
tty: true
Modrinth's CDN allows direct, unauthenticated downloads — unlike CurseForge, which blocks straightforward scraping. The project's version API resolves the latest compatible release and its declared dependencies:
curl -s "https://api.modrinth.com/v2/project/<slug>/version" \
-H "User-Agent: your-app-name/1.0"
/v2/project/<id> rather than assuming the version list's dependency names are self-evident;
it's an easy way to end up one jar short.
Unknown recipe serializerA player hit a decoder crash on connect referencing an unknown recipe serializer from a weapons-mod dependency. It looked like a client-side mod mismatch — the actual first cause was server-side.
The weapons mod in question expects an optional third-party content-pack directory separate from the normal mods folder, and it didn't exist. The pack's own item tags reference dozens of specific weapon IDs that only exist if the matching content packs are installed — since the directory was missing, none of those items registered, breaking enough of the recipe/tag graph that syncing recipes to a connecting client threw a decoder error.
Fix: created the expected directory and dropped the missing content-pack archives directly into it (as zips — some loaders scan the archives directly rather than expecting them unpacked), then restarted the container. Server log went from dozens of missing-reference errors to a clean boot.
After the extensions fix, a different player hit the exact same error message again — but this was a second, independent cause that happened to produce identical output. A modded Fabric server syncs its recipe data to every connecting client automatically, but a custom recipe serializer (the code that knows how to parse a given recipe type) only exists if the client also has the mod that registers it. The extensions fix made the server's recipe graph more complete — which meant more valid recipes than before were now reaching clients, making a pre-existing gap in client-side setup instructions show up more reliably than it had before.
The real fix here wasn't a server change at all — it was writing correct client setup documentation: bundling the exact mod jars the server actually runs into a single distributable zip, matched to the exact Fabric loader version running server-side (pulled directly off the server, not guessed from an installer version number).
Expect to see @Mixin target ... was not found warnings on boot for client-only rendering
classes that simply don't exist in a headless dedicated server — mods built for both client and server
gracefully skip these mixins server-side. Not a sign of a broken install; only worth investigating if the
server actually fails to reach a clean Done (...) boot line.