How to Fix Common Minecraft Server Errors

I’ve admined Minecraft servers that started as a couple friends on a Raspberry Pi and grew into weekend chaos with a hundred modded clients and a map the size of a small country. Over time, I learned there’s a rhythm to server errors. They strike at predictable choke points — startup, player join, world save, plugin or mod load, network handshakes, or I/O. When you know where to look and what the logs really say, the “mystery crash” turns into a 20‑minute fix and a good story for later.

This guide walks through the most common failure modes, how to diagnose them quickly, and what to do before a harmless warning grows teeth. I’ll call out specific error strings, share real fixes that worked under pressure, and make room for the weird edge cases that only show up on a Sunday evening when everyone’s online.

First, make the logs your compass

Every useful fix starts with logs. Console output is fine for a quick glance, but the real breadcrumbs live in latest.log in your server’s logs directory. On Paper or Spigot, the stack traces are clean and timestamped. On Forge or Fabric, expect longer traces and more mod chatter. Get into the habit of grabbing three things when an error hits: the immediate error block, the 30 seconds before it, and any “During the following phase” hints on modded servers. Most of my fastest fixes came from not chasing the error line, but the warning two dozen lines upstream.

If you don’t see logs at all, that’s its own diagnostic clue. A Java process that never starts is often a path issue, a permissions block, or an incompatible Java version.

Java version mismatches and memory flags that backfire

Version mismatch is a quiet killer. Vanilla 1.20+ runs on Java 17. Many modpacks on Forge 1.12.2 want Java 8, while newer Fabric packs often expect 17 or 21. When the versions don’t match, you’ll see errors like Unsupported class file major version or Could not initialize class net.minecraft.server.MinecraftServer.

If you manage multiple servers, install multiple JDKs and set explicit paths per service. On Linux, I’ll point a systemd unit at /usr/lib/jvm/temurin-17-jdk/bin/java for a 1.20 Paper server and keep /usr/lib/jvm/temurin-8-jdk for old packs. On Windows, batch files with fully qualified Java paths keep things predictable. Avoid system-wide JAVA_HOME guessing.

Memory flags cause a different flavor of crash. Xmx too small and the server dies under load; Xmx too large and you starve the OS page cache. A 6–8 GB heap suffices for a typical Paper survival with 10–20 plugins. Modded packs eat memory fast. A complex 1.18 Forge pack with 200+ mods is comfy at 10–12 GB and can use more, but watch GC pauses if you climb above 14 GB.

On modern JVMs, you don’t need half the folklore flags that float around. Start with -Xms equal to -Xmx, use G1GC on Java 17, and skip the arcane -XX flags unless you have a reason. I’ve removed pages of “optimization” flags that actually hurt performance and stability. If you see pauses longer than a second, lower Xmx first, then adjust GC logs to confirm.

EULA, ports, and the silly simple problems

Embarrassing because they’re easy, but you’ll hit them sooner or later. If the server simply exits without fanfare, check that eula.txt exists and says eula=true. If your friends can’t connect but you can, check that you’re advertising the right port and that the firewall isn’t blocking 25565. On hosts with provider firewalls, you need to open the port in both the VM and the provider panel. If your router supports UPnP and you rely on it, expect it to fail at the worst time. Manual port forwarding lasts longer than hope.

On some hosts, IPv6 is enabled by default and Minecraft clients might prefer it. If you bind server-ip to a v4 address while DNS points to a v6 AAAA record, clients may time out. Either bind to 0.0.0.0 or clean up your DNS.

The most common startup errors and how I unstick them

I keep a laminated “early boot triage” card. Here’s the condensed version I actually use.

    Check Java makes sense for the server jar. Confirm the server jar matches the world and plugin or mod ecosystem. Run once with a clean plugins or mods folder to see if the base server starts. Restore config and data step by step, watching logs for the line where it tips.

That’s the only list we’ll need for now.

When Paper or Spigot fails on load with something like Could not load 'plugins/SomePlugin.jar' in folder 'plugins', it usually means:

    The plugin targets a different API version. A 1.19 plugin may work on 1.20, but not always. Look for “Unsupported API version” in logs. If present, update or replace the plugin. The plugin’s dependencies are missing. For example, a protection plugin might require WorldEdit or Vault. The stack trace often mentions the missing class by package name: net.milkbowl.vault.economy. Add the dependency and reboot. The plugin jar is corrupted. Re-download from the original source. Avoid repacks from random mirrors.

Bukkit complaining about Duplicate key errors in a YAML file points to broken configuration. YAML cares about indentation and spacing. I’ve fixed dozens of these by pasting the file into a linter and correcting tabs to spaces. If the server says Cannot deserialize BlockData or similar, a config references blocks that don’t exist in your version.

Forge and Fabric present their own trio of errors: missing mod dependencies, wrong loader version, and classloading conflicts. Look for lines like Mod somemod requires forge 43.2.0. You might be on 43.1.3. Update the loader, not the modpack, unless you want a cascade. With Fabric, pay attention to your fabric-api version. A modpack built around Fabric API 0.90 won’t tolerate 0.75. If you see Mixin apply failed or Failed to load mixin config, you have mods fighting over the same hooks. Pull out the last-added mod and relaunch. When I don’t know which mod causes it, I bisect the mods folder: halve it, test, repeat. Five minutes later, you’re down to the ten troublemakers.

The world is fine until it isn’t: chunk corruption and region surgery

Hard power cuts, disk hiccups, or buggy mods corrupt chunks. Symptoms vary: players crash when entering a region, or the server throws Exception ticking world or java.lang.ArrayIndexOutOfBoundsException in chunk N. On Paper, watch for region warnings. You can often salvage the map by removing a specific .mca file from world/region. The world loads, but you lose a 512x512 area. I’ve done surgical recoveries where we copied a clean version of that region from last night’s backup and accepted a few missing builds rather than a full map wipe.

Some cases are entity-bound. A tile entity with bad NBT tags can crash the chunk. Tools like NBTExplorer let you remove the bad entity from the region file. If the crash report shows a specific block entity type — say, a modded hopper with nonsense tags — deleting just that entity saves the structure. Keep backups of the original file, work on a copy, and test on a staging server before touching production.

If you lack backups and the region is toast, WorldEdit can sometimes re-generate terrain to fill gaps after you remove a broken region. It’s a triage, not a cure, but it brings the server back online.

Player join failures, authentication oddities, and UUID headaches

The message Failed to verify username usually means the server is in online-mode=false while the client is authenticated, or Mojang’s auth servers are flaky. If Mojang’s status page shows issues, wait it out or set online-mode=false temporarily only if you understand the risks. Offline mode changes UUID calculations, which breaks permissions and inventories if you flip back later. I’ve seen servers lose player data after an online/offline toggle because the user identities are now different. If you must go offline for a short window, plan to map old UUIDs to new ones or restore from a backup after the outage.

BungeeCord or Velocity complicate the picture. If you run a proxy, each backend Spigot or Paper server must be in offline mode and use the proxy’s IP whitelist or secret. BungeeCord: set ip_forward to true, and on the backend servers, set bungeecord: true in spigot.yml. Velocity: use modern forwarding with a set forwarding-secret. If you forget this, you’ll get kicked with errors like If you wish to use IP forwarding, please enable it in your BungeeCord config. Worse, without firewalling the backend servers, anyone can connect directly and impersonate players. Always restrict backend ports at the network level or bind them to localhost.

Another sneaky join failure comes from plugins that hook the login event and throw non-obvious errors. If a permissions plugin can’t reach its database, it might silently deny joins. Check logs for SQLException near player join. If you rely on MySQL or MariaDB for permissions or chat formatting, your database is part of your uptime.

image

TPS drops, “Can’t keep up!” spam, and what the message really means

“Can’t keep up! Is the server overloaded?” isn’t a death sentence. It’s a signal that the main thread is missing tick deadlines. The cause could be worldgen, redstone storms, too many entities, plugin timers, or disk waits. I’ve watched the same message appear for opposite reasons on two servers: one because of 300,000 dropped items in a laggy raid farm, the other because someone thought a network storage mount would be a fine place to put the world folder.

On Paper, use timings to measure. timings on, reproduce the lag for a few minutes, timings paste, and read the report. Average tick cost near or above 50 ms means trouble. Identify heavy chunks, pluggable tasks, or world saves. Don’t chase micro-optimizations until you address the big rocks.

A few examples from real triage:

    Redstone clock storms: I once found 120 hoppers and 30 droppers spamming item transfers in a chunkloader. The timings report showed tile entity tick cost ballooning. Fix was a manual redesign and hopper timers set to sane intervals. Plugin task hammering: A chat plugin polled a remote API every tick. We changed it to async with a cache refresh every 15 seconds, and tick cost went from 12 ms to negligible. Entities after a mob farm event: ClearLag helps in moderation, but deleting all entities can wipe item frames and armor stands if misconfigured. Better to adjust mobcaps and fix the farm.

If you’re on a mechanical drive or an underpowered VPS, synchronous chunk saves will cost you. Paper offers async chunk I/O and configurable save intervals. I keep autosave on, but stretch the interval for stable hardware. On cheap hosts with noisy neighbors, consider extra RAM for filesystem cache and keep your world on local SSD, not network storage.

The mod or plugin that breaks only on Tuesdays

Race conditions and soft-dependency bugs show up sporadically. You’ll see reports like Occasionally, server hangs during shutdown. The log stops at Disabling PluginX. Or, Every few hours, chat stops formatting until a reload. These are hard to reproduce, but you can catch them by controlling your reload habits and boot order.

I avoid /reload on Paper or Spigot except for known-safe plugins, and never on Forge. Reload often leaves threads, hooks, or file watchers lingering. Use a staging server to test changes and hard restart production. For soft dependencies, ensure PluginB loads after PluginA if it depends on it by setting loadbefore or depend entries. With Forge, mod loading order is less direct, but missing optional dependencies still throw warnings you should heed. A “soft failure” might not crash the server, but it leaves features half-broken.

When a problem is intermittent, increase log verbosity temporarily. On Paper, set debug: true in paper.yml for a short window, then revert. Some plugins have their own debug flags. Gather structured evidence, narrow the window, and you’ll catch the thread that didn’t shut down or the scheduler job that runs too often.

Permission snafus that masquerade as errors

A surprising number of “errors” are behavior issues caused by missing permissions. Players can’t place blocks in certain regions, commands silently fail, or portals refuse to link. If you run LuckPerms, use the verbose feature while a player attempts a failing action. The log will show the exact permission node being checked. Many region plugins overlap permission checks in odd ways — for example, WorldGuard build permissions colliding with a land-claim system. Start by disabling one plugin’s protection features in a test area and verify the edge.

If you ever find yourself granting wildcards like plugin.* to fix a break, stop. That solves the symptom and opens security holes large enough to drive a ghast through. Map the exact nodes needed and give them to a properly scoped group. LuckPerms tracks changes and lets you roll back mistakes, which is worth its weight when a panic change at midnight goes sideways.

Backups, saves, and the day your disk fills

A full disk can look like corruption. The server tries to save, fails silently or throws a cascading error, and next boot you see region mismatches and missing player data. Monitor disk usage. If you can’t install external monitoring, a cron job that writes a timestamp file every five minutes to the world folder will at least give you a clue when writes fail.

Never host your only backups on the same machine. Nightly offsite copies of world, plugins/mods, and configs saved me more times than I can count. Compressed, a typical 5–8 GB world stores in under 2 GB. Keep a rolling window: yesterday, last week, last month. For modded servers, also store the exact modlist with versions — a simple export or manifest file — so you can rebuild an environment accurately.

Networking nuances: pings, proxies, and DNS

When players see io.netty.channel.AbstractChannel$AnnotatedConnectException or plain old Connection timed out, do a quick ladder: direct IP or domain, then traceroute, then host firewall. I’ve diagnosed packet loss caused by a datacenter route change by checking that latency to the server spiked from 40 ms to 300 ms only for a subset of ISPs. If you run via a proxy like Velocity for cross-server travel, keep your backend servers on a private network and check for MTU woes if you tunnel. Jumbo frames and mismatched MTUs can stall large packets in odd ways. Set conservative MTUs when in doubt.

If you front the server with a DDoS-protected provider that proxies TCP, ensure they support the Minecraft handshake on your chosen version and that SRV records are set properly. A common misconfiguration is an SRV record pointing to a hostname with no A record or to the wrong port. Test with a vanilla client using the raw IP:port to isolate DNS.

Crash-on-stop and zombie Java processes

Some servers don’t exit cleanly. I’ve seen Paper hang at Stopping the server, waiting for items to save because a plugin holds a file lock or blocks on an async task. To flush this out, stop the server on a quiet console and wait. If it takes longer than a minute, grab a thread dump with jstack. Hanging threads usually show a readable culprit — a scheduled executor waiting on a network future, a SQLite connection not closing, or a file watcher thread still alive. Report it upstream and consider disabling the plugin until patched.

If zombie Java processes linger, your control script may be sending SIGTERM but not SIGKILL, Gtop Minecraft servers or on Windows, a service wrapper might not handle stop commands. Use screen or tmux or a proper service manager that supervises the process and logs output cleanly.

The upgrade gauntlet: stepping versions without carnage

Upgrading Minecraft versions is where everything breaks at once. World format changes, plugin API shifts, mod loader updates. The safest path is incremental: move from 1.x to 1.x+1 on a copy with all plugins updated, let the server convert the world, then test every major feature under load. What burns most admins is skipping two or three versions in one jump and hoping the plugin ecosystem kept pace.

For modded packs, pin the mod versions. If you use a launcher manifest, update a few mods at a time and keep the pack bootable after each step. Watch for mods that changed item IDs or block names; migrations can drop inventories. We once handled a popular food mod update by warning players a week in advance and setting a grace period to convert items through a recipe before the update landed.

Never run a world conversion on your only copy. I keep a “museum” tier of backups that never change — a monthly archive stored offline. If everything goes wrong, at least the map survives.

Rare beasts: classpath pollution and path encoding

Every now and then, a server only breaks on a machine with non-English characters in file paths, or a mod jar with a strange character in its filename. Java handles Unicode well, but some libraries still choke. Keep your server directory paths clean ASCII with no spaces and short lengths. On Windows, I’ve hit mod loaders that barf on very long paths due to legacy path limits. Enable long path support or shorten the directory structure.

Classpath pollution happens when two plugins ship the same library with different versions shaded in, and only one wins. Symptoms include NoSuchMethodError for methods that you know exist. Paper plugins can use relocation to avoid conflicts. If a plugin repeatedly clashes, talk to the developer or switch alternatives.

When the fix is to change the shape of the gameplay

Sometimes technical fixes paper over a gameplay problem. If your server lags because players build twenty loaded farms per player, the real fix is a policy. Cap hopper speeds, limit chunk loaders, adjust mobcap rules, and communicate. I’ve enforced redstone rules on busy servers and the community accepted them because we were transparent about why. A server that stays up beats one that crashes elegantly.

Speed-run recipes for common error messages

I keep shorthand playbooks for the greatest hits. Here are five compact recipes that cover most panics.

    java.lang.OutOfMemoryError: Java heap space Raise -Xmx a bit if you have headroom, reduce mod count or view distance, check for plugin memory leaks with heap dumps if it recurs, and avoid massive pregen on tiny heaps. Unsupported class file major version Wrong Java version. Install the version the server or modpack expects and point your start script at it explicitly. Failed to load mixin config or Mixin apply failed Mod conflict. Remove the last-added mods, verify fabric-api or forge loader version, bisect the mods folder to identify the culprit, and check mod issue trackers for known conflicts. Could not load 'plugins/Name.jar' or Unsupported API version Plugin targets a different server version or misses dependencies. Update the plugin, add required libs like Vault or WorldEdit, and verify the plugin is not corrupted. Connection timed out or io.netty… errors for players only Check port forwarding and firewalls, verify DNS SRV records, test direct IP:port, ensure proxies are configured with forwarding and backend servers are firewalled from the public.

That’s our second and final list. Keep it handy.

Building habits that make errors rare and recoveries boring

The boring servers are the ones you remember fondly. You log in, the world is there, the TPS stays north of 19.8, and the chat is about builds, not crashes. Getting there means process, not heroics. Changes land on staging first. Backups run nightly and restore drills happen monthly. Start scripts reference explicit Java paths. Plugin and mod updates get notes. Logs are rotated and archived so you can answer what changed last week without guessing.

Most of the time, the quickest route to a fix is to subtract until the problem stops. Remove plugins until the server starts, then add back until it breaks. Split a modpack until the trace points to the guilty mod. Roll back the last two changes rather than the last twelve. The more you practice disciplined rollback, the less you need to become a stack-trace poet.

And when you do end up reading stack traces at midnight, remember the pattern: start with the first meaningful cause, not the last explosion. Look a page upstream. Trust your logs. Keep your cool. I’ve salvaged worlds that seemed beyond repair and watched servers thrive after we replaced three brittle plugins with one robust alternative. Minecraft servers may be finicky, but they aren’t inscrutable. Treat them like machines you can understand, and they’ll reward you with worlds that feel alive, week after week.