You don't need Pterodactyl, AMP, or any paid control panel to host a modpack. A Linux VPS, Ubuntu 24.04, and 20 minutes of terminal time is all it takes to run ATM10, Create: Astral, Vault Hunters, FTB Skies, Prominence II, or any other modpack on your own hardware. This guide walks through every modloader (Forge, Fabric, NeoForge, Quilt), the Java flags that actually matter for modded, and a RAM calculator that tells you exactly which VPS plan fits your pack and player count.
01 // Who this guide is for
You want to run a modded Minecraft server with friends or a small community — not a vanilla or Paper plugin server. You're comfortable with a Linux terminal but don't want to pay a monthly panel license or a managed-host markup. You want the server to actually run well, not just technically boot.
If you want the easy version — one-click install, web UI, zero Linux — jump to the managed alternative in §02. If you want full control, keep reading.
What this guide specifically covers:
- All four active modloaders: Forge, Fabric, NeoForge, Quilt — when to use which in 2026.
- Installing server files from CurseForge and Modrinth, including headless CLI downloads (no browser clicking through modal walls).
- Java version matching: Java 21 for 1.20.5+, Java 17 for 1.17–1.20.4, Java 8 for legacy packs.
- JVM flags that work for modded — Aikar's flags are not always the right answer for Forge.
- A modpack-aware interactive RAM calculator that sizes your VPS based on pack weight and slot count.
- systemd service, scheduled restarts, atomic backups (critical — modpack chunk corruption is real).
- A 12-row troubleshooting table for the errors you will actually hit (mixin crashes, missing client mods, modloader mismatch, etc.).
For general Paper / Purpur optimization, Aikar's flags explained, and spark profiling, see our dedicated Minecraft Java Optimization guide. This page is strictly about modded servers — different flags, different gotchas, different hardware floor.
02 // Hosting: self-hosted VPS vs managed
There are two honest paths to a working modpack server. Pick one before you read anything else — the rest of this guide only matters if you go the self-hosted route.
Option A — Self-hosted on a Linux VPS (recommended for most readers)
You rent a virtual server, SSH in, install Java, drop in the modpack files. You own the box. You pay for RAM, not for a control panel. A 16 GB VPS that comfortably runs ATM10 for 10 players costs roughly €13/month — the same RAM on a managed modded host is typically €25–40/month because they're reselling VPS resources plus a panel license.
The tradeoff is 20 minutes of one-time Linux work. After that, you have SSH access, full log visibility, no slot limits, and you can move the server to a different provider in 10 minutes with a tar and an scp.
Hostinger KVM 4 — 16 GB RAM, 4 vCPU, 200 GB NVMe
16 GB is the floor for any real modpack. Packs like ATM10, Create: Astral, and Vault Hunters will allocate 10–12 GB to the JVM at peak, and you need headroom for the OS, cron backups, and chunk generation bursts. 4 vCPU matters more than raw GHz for modded — each loaded chunk is processed on the main thread, but mod tick tasks and chunk IO spread across cores.
€12.99/month on the 12-month plan. Same spec on a managed modded host runs €25–35/month.
Get Hostinger KVM 4 →Hostinger KVM 8 — 32 GB RAM, 8 vCPU, 400 GB NVMe
If you're running a "kitchen sink" pack (600+ mods), a public server with 20+ concurrent players, or planning to host two modpacks on one box, step up to KVM 8. 32 GB lets you allocate 20–24 GB to a single modpack JVM without OOM risk during chunk-loading spikes. €24.99/month.
Get Hostinger KVM 8 →Option B — Managed modded hosting
If you will never SSH into a Linux server no matter how many tutorials I write, pay for a managed host. You get a web UI, a one-click modpack installer (they handle CurseForge API keys and download quotas for you), and 24/7 support. You pay roughly 2× the equivalent VPS cost, and you're locked into their panel.
Shockbyte — Dedicated Modpack Host
Shockbyte is one of the most recommended managed Minecraft hosts — they specialize in Minecraft only, so their stack is tuned for Forge / Fabric / NeoForge modpacks out of the box. One-click modpack installer with full CurseForge and Feed the Beast library, automatic Java version matching, per-pack RAM presets, free subdomain, free MySQL, DDoS protection, and 24/7 Minecraft-literate support. Best for 1–4 GB light modpacks or beginners running their first pack. Trade-off: per-GB pricing gets steep past 8 GB (heavy kitchen-sink packs), and you can’t install system-level tools like Spark or Chunky — that’s where a self-hosted KVM 4 wins.
Get Shockbyte →A KVM 4 at €13/month outperforms most €25/month managed modded servers because managed hosts heavily oversubscribe their boxes. The only real reason to pick managed is if you value your time at more than €50/hour and want to skip a one-time 20-minute setup. Otherwise: self-host.
03 // Pick the right modloader
Before you download anything, figure out which modloader your pack uses. It's almost always on the pack's CurseForge or Modrinth page next to the Minecraft version. Get this wrong and the server won't boot — Forge mods will not run on Fabric, NeoForge is not a drop-in for Forge past 1.20.1, and Quilt is Fabric-compatible but not Forge-compatible.
| Loader | Version range | Typical packs | When to use it |
|---|---|---|---|
| Forge | 1.7 – 1.20.1 (legacy path continues) | ATM9, Enigmatica 2, older FTB packs, Vault Hunters up through 1.18.2 | You're running an older pack or a pack that explicitly requires Forge. Largest historical mod catalog, heaviest runtime. |
| NeoForge | 1.20.1+ (the Forge fork that won) | ATM10, Prominence II Fabletime (NeoForge branch), most 2024–2026 Forge-style packs | Default choice for any modern Forge-ecosystem pack. Almost every big Forge pack has migrated. Faster dev pace than upstream Forge. |
| Fabric | 1.14+ | Create: Astral, Cobblemon, Adrenaserver, Simply Skyblock, performance-focused packs | Your pack ships a fabric.mod.json instead of META-INF/mods.toml. Lighter runtime than Forge/NeoForge, better TPS per RAM GB. |
| Quilt | 1.18+ | Some community forks of Fabric packs | Rare in modpacks. Fabric-compatible — if a pack says Quilt, you can usually run it on Fabric and save yourself a step. |
New pack on 1.20.1 or later and has Create / tech mods → NeoForge. New pack with performance mods (Lithium, Sodium server-side) → Fabric. Old pack locked to 1.18.2 or earlier → Forge. Don't overthink it — the pack page tells you.
04 // Install Java (version matters)
Minecraft 1.20.5 and later require Java 21. Anything older than Java 21 will hard-refuse to boot with a cryptic NoClassDefFoundError. Conversely, running Java 21 against a 1.16 pack will also fail. Match the Java major version to the Minecraft version:
- Minecraft 1.20.5+ (most 2025–2026 packs): Java 21
- Minecraft 1.17 – 1.20.4: Java 17
- Minecraft 1.12 – 1.16: Java 8 (yes, really — legacy Forge needs it)
On Ubuntu 24.04, use Eclipse Temurin — the same distribution most modded hosts run. It's free, well-tested, and ships headless.
# Add Adoptium's repo and install Java 21 headless
sudo apt update
sudo apt install -y wget apt-transport-https gnupg
wget -O - https://packages.adoptium.net/artifactory/api/gpg/key/public \
| sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/adoptium.gpg
echo "deb https://packages.adoptium.net/artifactory/deb $(. /etc/os-release; echo $VERSION_CODENAME) main" \
| sudo tee /etc/apt/sources.list.d/adoptium.list
sudo apt update
sudo apt install -y temurin-21-jre
# Verify
java -version
# openjdk version "21.0.x" 2025-xx-xx LTS
If you need multiple Java versions on the same box (e.g. one modpack on 1.18.2, another on 1.20.6), install both with temurin-17-jre and temurin-21-jre, then invoke the specific binary from your systemd unit — don't rely on update-alternatives.
05 // Download the modpack server files
There are three realistic sources for a modpack server pack. Pick the one that matches where you got the pack:
CurseForge (most common)
Almost every pack ships a "Server Files" download on its CurseForge page, separate from the client download. Find the pack, click the Files tab, filter to Server or look for a zip named like ATM10-3.7.2-Server.zip.
CurseForge tries to force you through a browser modal for downloads. On a headless VPS you have two options:
- Download on your laptop, scp to server. Simplest.
scp ATM10-Server.zip user@vps:/home/mc/ - Use the direct CDN URL. On the CurseForge Files page, right-click the download button → Copy Link. The resolved URL points at
mediafilez.forgecdn.netand iswget-able directly.
# Example — once you have the direct URL:
mkdir -p /home/mc/modpack && cd /home/mc/modpack
wget -O server.zip 'https://mediafilez.forgecdn.net/files/xxxx/yyyy/ATM10-Server.zip'
unzip server.zip
ls -la # should show a startserver.sh or run.sh script
Modrinth
Modrinth is cleaner — no download modals, direct URLs work. On the modpack page, click Versions → pick latest → the .mrpack file is a zip you can download directly. But you can't just unzip it and run: .mrpack files reference mods by URL and expect a launcher to resolve them.
The clean way to convert a .mrpack to a runnable server is mrpack-install, a small Go binary that reads the pack manifest and pulls every mod server-side:
# Install mrpack-install (one-time, latest release)
wget https://github.com/nothub/mrpack-install/releases/latest/download/mrpack-install-linux \
-O /usr/local/bin/mrpack-install
chmod +x /usr/local/bin/mrpack-install
# Use it:
mkdir -p /home/mc/modpack && cd /home/mc/modpack
mrpack-install ./CreateAstral-2.0.mrpack \
--server-dir /home/mc/modpack
# It downloads the Fabric/NeoForge server, all mods, and configs.
Feed the Beast (FTB App packs)
FTB packs use their own launcher format. On the FTB site, every pack has a Server Files link that produces a standalone zip — same workflow as CurseForge. Nothing special, just a different host.
You do not need the client-side modpack installed on your VPS. Ever. The server pack is a completely different archive that only contains server-compatible mods, sided correctly. Don't waste disk on client assets.
06 // Create a non-root user and lay out the files
Never run Minecraft as root. Create a dedicated system user, drop the files in their home, own everything correctly.
sudo adduser --system --group --shell /bin/bash --home /home/mc mc
sudo mkdir -p /home/mc/modpack
sudo chown -R mc:mc /home/mc
sudo -iu mc
# As the mc user, move/unzip your server files into /home/mc/modpack/
cd /home/mc/modpack
unzip ~/ATM10-Server.zip -d .
ls
# You should see: forge/NeoForge installer jar, mods/, config/, libraries/,
# a startserver.sh or run.sh, user_jvm_args.txt, eula.txt
Accept the EULA (yes, even on your own server — the vanilla jar refuses to run otherwise):
echo "eula=true" > /home/mc/modpack/eula.txt
07 // Run the modloader installer
Most modern server packs ship either a pre-installed server (just run ./run.sh) or a standalone installer jar you have to execute once. Pick the path your pack uses:
Pre-installed server (ATM10, most 2024+ NeoForge packs)
Look for run.sh or startserver.sh in the root of the unzipped folder. If it exists, you're done installing — skip to §08.
cd /home/mc/modpack
ls run.sh user_jvm_args.txt
chmod +x run.sh
NeoForge installer jar
If the pack ships something like neoforge-21.1.x-installer.jar, run it once in server mode:
cd /home/mc/modpack
java -jar neoforge-21.1.x-installer.jar --installServer
# This downloads libraries and writes run.sh + user_jvm_args.txt.
# Takes 30–90 seconds depending on VPS bandwidth.
Forge installer jar (legacy 1.20.1 and older)
cd /home/mc/modpack
java -jar forge-1.20.1-47.2.x-installer.jar --installServer
# Produces forge-1.20.1-47.2.x.jar plus libraries/.
# Older Forge produces run.bat/run.sh; for very old packs, a ServerStart.sh.
Fabric installer
Fabric doesn't ship with packs — you fetch it separately and then drop the mods folder on top:
# Latest Fabric installer
wget https://meta.fabricmc.net/v2/versions/installer \
-O fabric-installer.json
# pick the latest stable from that JSON, then:
wget https://maven.fabricmc.net/net/fabricmc/fabric-installer/X.Y.Z/fabric-installer-X.Y.Z.jar
# Install Fabric server for MC 1.21.1 (replace versions to match pack)
java -jar fabric-installer-X.Y.Z.jar server \
-mcversion 1.21.1 -downloadMinecraft
# Produces fabric-server-launch.jar.
08 // First boot — generate configs, then stop
Boot the server once in the foreground so it generates server.properties, ops.json, and the world folder. It will run for a minute and stop if you stop-command it.
cd /home/mc/modpack
./run.sh # or bash run.sh
First boot of a large pack can take 5–15 minutes. Every mod's initial registry pass runs on the main thread; this is normal. Watch the log — if you see "Done (720.5s)! For help, type "help"", the server is up. Type stop and hit Enter.
09 // server.properties tuning for modded
Open server.properties in your editor. The defaults are tuned for vanilla; modded needs different numbers.
# Critical changes for modded servers
view-distance=8 # Vanilla default 10 is painful on modded. 8 or even 6.
simulation-distance=6 # Separate from view-distance since 1.18. Keep tight.
max-tick-time=-1 # IMPORTANT. Default 60000 (60s) will watchdog-kill
# your server during big chunk-gen spikes on modded.
network-compression-threshold=256
max-players=10 # Match your VPS's real capacity, not wishful thinking.
enable-command-block=false
spawn-protection=0 # Disable unless you run a public hub.
server-port=25565
motd=My Modded Server
Set max-tick-time=-1 on every modded server. The default 60-second watchdog will kill your server during legitimate long ticks (big tree growth, mekanism pipe rebuilds, chunk-loading on a fresh world). Server crashes mid-tick = chunk corruption. This one line prevents hours of restore work.
10 // JVM flags for modded (Aikar's flags are not always right)
Aikar's flags are famous — and they were written for Paper, not Forge. On heavily modded servers, some of Aikar's values (particularly G1NewSizePercent=30) cause more young-gen pressure than modded workloads want, because modded mod-tick objects live longer than plugin objects. The result is more frequent full GC pauses on big modpacks.
For modded servers, use these flags as your starting point. They're based on Forge and NeoForge community testing across ATM9, ATM10, Create: Astral, and Vault Hunters:
# For 8–12 GB heap (ATM10, Create Astral, most modpacks)
# Open user_jvm_args.txt and set:
-Xms10G
-Xmx10G
-XX:+UseG1GC
-XX:+ParallelRefProcEnabled
-XX:MaxGCPauseMillis=50
-XX:+UnlockExperimentalVMOptions
-XX:+DisableExplicitGC
-XX:+AlwaysPreTouch
-XX:G1HeapRegionSize=8M
-XX:G1NewSizePercent=20
-XX:G1MaxNewSizePercent=40
-XX:G1ReservePercent=20
-XX:InitiatingHeapOccupancyPercent=15
-XX:G1MixedGCLiveThresholdPercent=90
-XX:SurvivorRatio=32
-Dusing.aikars.flags=https://mcflags.emc.gs
-Daikars.new.flags=true
Key differences from vanilla Aikar's:
G1NewSizePercent=20(vs 30 in Aikar's): modded objects survive longer, shrinking young-gen reduces promotion churn.G1HeapRegionSize=8Mexplicit: ensures large-object allocations (BlockState arrays, big item maps) don't fragment.MaxGCPauseMillis=50: tighter than default 200 — prevents visible lag spikes on single-threaded tick.Xms=Xmx: always equal. Never let the JVM grow the heap dynamically on a dedicated server.
Allocate 70–75% of your VPS RAM to the JVM, never more. On a 16 GB KVM 4, that's -Xmx10G or -Xmx11G max. The rest is for the OS, the kernel page cache (which speeds up chunk IO massively), and cron/backup jobs. A 16 GB VPS running with -Xmx16G will get OOM-killed during any backup or chunk-loading spike.
For 16–24 GB heap (heavy packs, 20+ players)
# KVM 8 with 32 GB RAM, running one big pack
-Xms20G
-Xmx20G
-XX:+UseG1GC
-XX:+ParallelRefProcEnabled
-XX:MaxGCPauseMillis=100 # Slightly higher at big heap sizes
-XX:+UnlockExperimentalVMOptions
-XX:+DisableExplicitGC
-XX:+AlwaysPreTouch
-XX:G1HeapRegionSize=16M # Larger regions for larger heap
-XX:G1NewSizePercent=30
-XX:G1MaxNewSizePercent=50
-XX:G1ReservePercent=20
-XX:InitiatingHeapOccupancyPercent=15
-XX:G1MixedGCLiveThresholdPercent=90
-XX:SurvivorRatio=32
Drop those into user_jvm_args.txt (modern NeoForge / Forge use this file automatically) or directly into your run.sh if it invokes Java manually. Restart the server, watch latest.log for the first 5 minutes — you should see no lines about "Full GC" during normal play.
11 // Interactive RAM calculator
Answer two questions and get the exact VPS plan and JVM heap size for your pack. The recommendations come from real production servers, not marketing copy.
12 // systemd service (auto-start, auto-restart)
You want the server to boot with the VPS, restart on crash, and be manageable with systemctl like any other Linux service. A screen-based setup works for testing but is the wrong answer for production.
Create /etc/systemd/system/minecraft.service:
[Unit]
Description=Minecraft Modpack Server
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=mc
Group=mc
WorkingDirectory=/home/mc/modpack
ExecStart=/home/mc/modpack/run.sh
ExecStop=/bin/bash -c 'screen -p 0 -S mc -X stuff "stop\r" 2>/dev/null || kill -SIGINT $MAINPID'
Restart=on-failure
RestartSec=10s
TimeoutStopSec=90s
LimitNOFILE=65536
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
The TimeoutStopSec=90s matters — a modpack save-all + stop on a large world can take 30–60 seconds. Default 5s will SIGKILL the server mid-save and corrupt chunks.
sudo systemctl daemon-reload
sudo systemctl enable --now minecraft
sudo systemctl status minecraft
# Watch live output:
sudo journalctl -u minecraft -f
systemd doesn't give you an interactive console by default. To run in-game commands, either enable RCON in server.properties (enable-rcon=true, rcon.password=...) and use a client like mcrcon, or wrap run.sh in a named screen session. RCON is cleaner for production.
13 // Backups (not optional on modpacks)
Modpack worlds corrupt more often than vanilla worlds. Every mixin patch, every broken mod update, every OOM during chunk-save is a chance at a zero-byte region file. Back up daily, keep at least two weeks, and store off the VPS.
The safe way to back up is with the server running, by pausing saves first via RCON:
#!/usr/bin/env bash
# /home/mc/backup.sh — run nightly via cron
set -euo pipefail
MC_DIR="/home/mc/modpack"
BACKUP_DIR="/home/mc/backups"
RCON_PASS="yourlongrandompassword"
RCON_PORT=25575
STAMP=$(date +%Y%m%d-%H%M)
mkdir -p "$BACKUP_DIR"
# Flush and pause saves so tar gets a consistent snapshot
mcrcon -H 127.0.0.1 -P $RCON_PORT -p "$RCON_PASS" "save-all flush" "save-off" || true
sleep 3
# Tar the world folder only (world/, world_nether/, world_the_end/ — depends on pack)
tar -czf "$BACKUP_DIR/world-$STAMP.tar.gz" -C "$MC_DIR" world world_nether world_the_end 2>/dev/null || \
tar -czf "$BACKUP_DIR/world-$STAMP.tar.gz" -C "$MC_DIR" $(ls "$MC_DIR" | grep '^world')
# Re-enable saves
mcrcon -H 127.0.0.1 -P $RCON_PORT -p "$RCON_PASS" "save-on" "save-all" || true
# Keep last 14 days
find "$BACKUP_DIR" -name 'world-*.tar.gz' -mtime +14 -delete
# Install mcrcon once
sudo apt install -y build-essential git
git clone https://github.com/Tiiffi/mcrcon.git /tmp/mcrcon
cd /tmp/mcrcon && make && sudo install -Dm755 mcrcon /usr/local/bin/mcrcon
# Cron as mc user
chmod +x /home/mc/backup.sh
crontab -u mc -e
# Add:
0 4 * * * /home/mc/backup.sh >> /home/mc/backup.log 2>&1
A backup on the same disk as the running server will not save you when the VPS disk fails or the provider accidentally deletes your instance. Rsync or rclone the /home/mc/backups/ directory to a cheap object store (Backblaze B2, iDrive e2, Wasabi) nightly. Cost: under €1/month for 20–50 GB of modpack worlds.
14 // Scheduled restarts
Long-running modded JVMs accumulate off-heap memory and mod-specific object pools that never fully clean up. A nightly restart keeps tick times predictable. Use systemd timers or a cron + systemctl restart:
# /etc/systemd/system/minecraft-restart.timer
[Unit]
Description=Nightly Minecraft restart
[Timer]
OnCalendar=*-*-* 05:00:00
Persistent=true
[Install]
WantedBy=timers.target
# /etc/systemd/system/minecraft-restart.service
[Unit]
Description=Restart Minecraft
[Service]
Type=oneshot
ExecStart=/bin/bash -c '/usr/local/bin/mcrcon -H 127.0.0.1 -P 25575 -p "$RCON_PASS" "say Restarting in 60 seconds"; sleep 55; /usr/local/bin/mcrcon -H 127.0.0.1 -P 25575 -p "$RCON_PASS" "say Restarting now"; /bin/systemctl restart minecraft'
Environment=RCON_PASS=yourlongrandompassword
sudo systemctl daemon-reload
sudo systemctl enable --now minecraft-restart.timer
sudo systemctl list-timers | grep minecraft
15 // Adding or removing mods after install
Two rules prevent 90% of modpack problems:
- Server mods and client mods must match on every client-required mod. Client-only mods (shaders, minimap, JEI themes) never go on the server. Server-only mods (Spark, LuckPerms) never go in the client. "Both-sided" mods — the majority — must be identical version on both.
- Never hot-edit mods on a live server. Stop the server with
systemctl stop minecraft, drop or remove the jar, start again. Adding a jar while the JVM is running will not load it and can corrupt the mod registry on next save.
To check which mods are server-side, look inside the jar:
# NeoForge / Forge
unzip -p mymod.jar META-INF/mods.toml | grep -E '^(displayName|side)'
# Fabric
unzip -p mymod.jar fabric.mod.json | grep -E '"(name|environment)"'
If you see side="CLIENT" or "environment": "client", don't put it on the server.
Giving players the mod list
Players joining a modded server need the client pack. Options:
- Publish the same pack on CurseForge/Modrinth. Simplest for public servers. Players install through their launcher.
- Host the client zip on the server domain. If
nginxis already running, dropmodpack-client.zipin/var/www/html/and link it in your Discord. - Use a resource pack for texture-only additions. Those auto-download if you set
resource-pack=inserver.properties. Doesn't work for actual mods — only for textures/models.
"Leaked" paid modpacks and stripped versions of patreon-only packs circulating on Reddit or random Discord servers regularly ship with coin miners or RAT payloads. This is not a theoretical problem — it's a monthly event in the modded community. Only pull packs from official CurseForge, Modrinth, or FTB sources. If a pack's creator is alive and active, support them; if a pack is abandoned, use the last official release, not a repack.
16 // Troubleshooting — the 12 errors you will actually hit
Every entry comes from real pack-hosting incidents. Match the symptom, read the fix.
| Symptom in logs | Root cause | Fix |
|---|---|---|
UnsupportedClassVersionError ... class file version 65.0 |
Running Java 17 against a Java 21 pack (MC 1.20.5+). | Install temurin-21-jre and point run.sh at /usr/lib/jvm/temurin-21-jre/bin/java. |
Mixin apply failed ... org.spongepowered.asm.mixin.transformer |
Two mods patching the same method, incompatible versions. | Read the full mixin error — it names both mods. Update both, or remove the newer/less-critical one. Many modpacks ship a mixin.whitelist or known-conflict list in defaultconfigs/. |
Cannot invoke ... because "FMLEnvironment.dist" is null |
Client-only mod placed in the server mods/ folder. |
Identify with unzip -p mod.jar META-INF/mods.toml | grep side. Remove any mod where side="CLIENT". Common offenders: JEI themes, minimaps, shader packs. |
java.lang.OutOfMemoryError: Java heap space |
Heap too small for the pack, or Xmx set but Xms low so heap didn't pre-allocate. |
Set -Xms=Xmx. Run the calculator in §11. If you're already at 75% of VPS RAM, upgrade the plan — not the flags. |
Server gets SIGKILL / disappears with no stack trace |
Linux OOM-killer shot the JVM. Check sudo dmesg | grep -i kill. |
Lower -Xmx; you're letting the JVM consume more than the VPS physically has. Rule: Xmx ≤ 75% of total RAM. |
Watching Server ... Can't keep up! Is the server overloaded? followed by crash |
max-tick-time watchdog killed the server during a big legit tick. |
Set max-tick-time=-1 in server.properties. Re-read §09. |
Failed to connect to the server: Connection timed out (but server log says ready) |
VPS firewall blocking port 25565 or bound to 127.0.0.1 only. | sudo ufw allow 25565/tcp and check server-ip= is empty in server.properties (empty = bind all interfaces). |
Mod ID 'examplemod' is missing on client |
Pack on server has a mod the player's client pack doesn't. | Republish the client zip. Check mod file names match exactly, including version. A create-1.20.1-0.5.1.f.jar and create-1.20.1-0.5.1.e.jar are different mods to Forge. |
Corrupt NBT ... chunk [r.X.Y.mca] on startup |
A region file got truncated — usually from prior OOM or SIGKILL mid-save. | Stop the server. Restore that region file from your latest backup (§13). If no backup, MCASelector can delete the corrupt chunk — players re-explore that area. |
Unresolved dependency on mod 'forge' with version range [47.0,) |
You ran the wrong modloader — Forge pack on NeoForge or vice versa. | Check the pack's CurseForge page. Re-run the installer for the correct loader. See §03 for the 2026 migration map. |
| Server takes 10+ minutes to boot on subsequent restarts | Chunk scanning on boot — usually from level.dat resizing or large world. |
Normal for 50+ GB worlds. Pre-generate with Chunky in a controlled time window, then ongoing boots are fast. See our Java Optimization guide. |
| TPS drops to <15 with no players online | A broken mod is running a tick loop (common in abandoned mods or beta builds). | Install Spark (server-side only). Run /spark profiler start, wait 60s, /spark profiler stop. The report names the offending mod in seconds. |
17 // Next steps
- Monitor tick performance — install Spark on the server. One command (
/spark tps) tells you your real tick rate. Essential for any modded server beyond week one. - Pre-generate your world — use Chunky to generate a 5000×5000 area overnight. First-visit lag during play drops to near zero. See our Java Optimization guide.
- Harden SSH — keys only, disable password auth, fail2ban. Basic VPS hygiene; see our hardening notes in the Pelican guide (applies identically here).
- Consider a panel later — if you end up running 3+ modpack servers, Pelican or Pterodactyl start to pay for themselves in management time. For one pack, systemd is fine.
- Set up a Discord integration — Discord Integration (server-side only) bridges chat and uptime alerts to Discord. 5-minute install, huge community value.
18 // Final thoughts
Self-hosting a modpack is not hard — it's a one-evening setup that pays for itself in month one. The hard part isn't Linux; it's the modpack ecosystem's quirks: matching Java versions, reading mixin errors, surviving your first chunk corruption. Everything in this guide came from real server logs, not documentation theory.
A Hostinger KVM 4 running ATM10 or Create: Astral for 10 friends will cost you €13/month and outperform most €30/month managed modded hosts. The €17/month difference — over a year — buys you the next KVM 8 upgrade outright. That's the whole pitch.
If you get stuck, the troubleshooting table in §16 covers 90% of real failures. The other 10% are pack-specific; the pack's GitHub issues page or Discord is usually where the answer lives.