A network is several Minecraft servers that look like one: players join one address, land in a lobby and hop to survival, skyblock or minigames without disconnecting. The piece that makes it work is a proxy, and the proxy the Paper team itself recommends today is Velocity. This guide builds a network from scratch with complete config files, and covers the parts most guides skip: locking down the backends, Geyser for Bedrock players, Forge and Fabric backends, mixed versions, and the exact error messages you will see in the console.
Everything technical here was checked against the official Velocity, Paper and Geyser documentation in October 2026. Versions mentioned (Minecraft 26.3, Velocity 4.2, Paper 26.3) are current at that date; the mechanics are the same on older versions except where noted.
Do you actually need a network?
Not always. If you run a survival server and want to add a creative world, a multiworld plugin on one server does it with no proxy. A network pays off when:
- The game modes cannot coexist in one process (a Paper survival and a Forge modpack, say).
- One mode is busy enough to drag the others' TPS down if they shared a JVM.
- You want to restart or crash one mode without kicking everyone.
- You have enough players to fill more than one server at once.
Ten friends on a survival server do not need it yet. Forty or fifty concurrent players across two incompatible modes do.
How it works
The proxy listens on the public port (the address you hand out), authenticates each player with Mojang and routes them to the right server. The servers behind it, the backends, never talk to the player directly. That has one huge security consequence we fix in step 4: backends must run with online-mode=false, and if they are reachable from the internet, anyone could join one pretending to be any player.
Velocity vs BungeeCord: Paper's own comparison page recommends Velocity over BungeeCord and Waterfall, and notes Waterfall has reached end of life. The difference that matters is that only Velocity has secure player-information forwarding ("modern forwarding"), it is the most resource-efficient of the three, and it is where development happens. BungeeCord still works, and its plugins do not run on Velocity, so a hard dependency on a Bungee-only plugin is the one reason to stay. Starting fresh, pick Velocity.
What you need
- One server for the proxy. Velocity is light: the official start script gives it 1 GB, which covers hundreds of players. Velocity 4.x requires Java 25.
- One server per game mode. Lobby, survival, minigames, modpack, each with RAM sized for what it runs. A lobby is small (2-4 GB is plenty); a modpack is whatever the pack needs. Use the RAM calculator per server, not for the sum.
- Each backend's IP and port. On a hosting panel every server has its own IP:port; write them down.
At TaroHosting every piece is a server in the panel (Velocity is an installable server type), each with its own console, backups and DDoS protection, so you do not need a VPS; VPS vs hosting covers when a VPS makes sense anyway.
Step 1: prepare the Paper backends
Install Paper (or Purpur) on each game server, on the version your players will use. Start each once to generate its files, then on each backend:
- In
server.propertiessetonline-mode=false. The docs are explicit: this stops the backend from authenticating players, because the proxy does that instead. - In
spigot.ymlkeepsettings.bungeecord: false. It must be false for Velocity modern forwarding. - Note the port of each backend. If the proxy and backends share one machine and your host allows it,
server-ip=127.0.0.1on each backend hides them from the internet; on multi-node hosting that is not always possible, and step 4 handles it.
Step 2: install Velocity and generate its config
On the proxy server, with the Velocity jar from papermc.io and Java 25, start it once. The first boot creates velocity.toml and forwarding.secret, a random key you will paste into every backend. Stop the proxy with end and edit velocity.toml. A minimal, working config for a lobby, a survival server and a minigames server:
bind = "0.0.0.0:25565"
motd = "<#09add3>My Network</#09add3>"
show-max-players = 500
online-mode = true
force-key-authentication = true
player-info-forwarding-mode = "modern"
forwarding-secret-file = "forwarding.secret"
[servers]
lobby = "LOBBY_IP:PORT"
survival = "SURVIVAL_IP:PORT"
minigames = "MINIGAMES_IP:PORT"
try = [ "lobby" ]
[forced-hosts]
"survival.yournetwork.com" = [ "survival" ]
bind: the proxy's public port. On a panel it is the port you were assigned, not necessarily 25565.motd: MiniMessage format only, not legacy&acodes. The MOTD generator helps.show-max-players: cosmetic; Velocity has no player cap here.online-mode = true: the proxy authenticates with Mojang. An offline network changes it here and only here.player-info-forwarding-mode = "modern": recommended by the docs for 1.13+.legacyexists for 1.12 compatibility and the docs call it fundamentally insecure;bungeeguardis legacy plus a token for shared hosts.[servers]: each backend's address.tryis the order the proxy attempts on login and after a kick from a server.[forced-hosts]: optional; lets a hostname send players straight to one backend.
Step 3: enable modern forwarding on each backend
Copy the contents of the proxy's forwarding.secret. On every backend open config/paper-global.yml and fill in the Velocity block:
proxies:
velocity:
enabled: true
online-mode: true
secret: "PASTE_THE_forwarding.secret_VALUE_HERE"
Three things the docs stress: online-mode in this block must match the proxy's online-mode; the secret must be identical on the proxy and every backend; and on Paper 1.18.2 or lower these options lived in paper.yml under settings.velocity-support. Restart the backends, then start the proxy.
Test: join through the proxy's address. You should land in the lobby and the lobby console should show your real UUID, not an offline one. Move around with /server survival.
Step 4: lock the backends down (not optional)
Velocity's security page says it plainly: with backends in offline mode, someone who reaches them directly could in theory impersonate any player, and modern forwarding is not a replacement for a firewall. From safest to least safe:
- Firewall: each backend's port accepts connections only from the proxy's IP. On a VPS that is an iptables or ufw rule; on a hosting panel, ask support whether backend ports can be restricted to the proxy IP.
- Same machine: if proxy and backends share a host,
server-ip=127.0.0.1on each backend and127.0.0.1:portaddresses invelocity.toml. The backends then do not listen on the internet at all. - A guard plugin (BungeeGuard-style, or Velocity's
bungeeguardmode): better than nothing, but Spigot's firewall guide is clear that it is not as secure as a firewall.
Do this before opening the network to the public, not after the first incident.
Step 5: shared permissions and data
Each backend runs its own plugins. What a network usually wants is the same ranks everywhere, and LuckPerms does that when every instance (one per backend, optionally one on the proxy) points at the same MySQL or MariaDB database rather than local files. In each LuckPerms config: storage-method: mysql with identical credentials, messaging-service: pluginmsg for a single proxy (redis for several), and a distinct server name per instance so you can grant permissions "only on survival". LuckPerms on the proxy only handles proxy-plugin checks; game permissions are checked by the backends, so it always goes there too.
Shared economy, inventories and stats are a different project: they need network-aware plugins with a central database, and that is where large networks spend their time. Start with shared permissions and add the rest when the community asks.
Step 6: Bedrock players on the network (Geyser on the proxy)
The Geyser wiki is blunt: on a network, install Geyser only on the proxy, never on the backends. Drop Geyser-Velocity.jar and Floodgate-Velocity.jar into the proxy's plugins/ folder, start it, and in plugins/Geyser-Velocity/config.yml set auth-type: floodgate so Bedrock players join without a Java account. Geyser listens on port 19132 by default and uses it over both UDP and TCP, so that port must be open for both protocols and cannot be the proxy's own port.
Two warnings from the docs. Geyser presents itself to the network as a Java client of the newest version it supports (26.3 today), so every backend must accept that version; a backend on an older version needs ViaVersion installed on it. And if you want the Floodgate API on a backend (so a plugin can tell Bedrock players apart), install Floodgate there too, set send-floodgate-data: true in the proxy's Floodgate config, and copy the proxy's key.pem into that backend's Floodgate folder. That key is never shared with anyone.
First time with Geyser? The crossplay guide covers the single-server case, and the "Outdated Geyser proxy" message after each game update is covered in the connection errors guide.
Step 7: different versions on one network
If survival runs 26.3 and minigames stay on an older version for its plugins, players could not hop between them. ViaVersion fixes that and can be installed on the proxy or on the backends; the docs say one place is enough, and warn that on the proxy the backends' anticheat may perform worse. ViaBackwards lets older clients into a newer server; ViaRewind covers 1.7 and 1.8 clients.
Step 8: Forge, NeoForge and Fabric backends
A modded backend has to understand modern forwarding, and the loaders do not ship it. On Fabric install FabricProxy-Lite (Fabric has no supported legacy-forwarding mod, so the mode must be modern); on Forge 1.14+ use ProxyCompatibleForge. Modpack servers are also slow to answer the proxy during startup and dimension changes, and Velocity drops them on timeout: the official FAQ recommends raising read-timeout in the [advanced] section of velocity.toml and -Dfml.readTimeout on the backend to the same value in seconds (for example read-timeout = 120000 and -Dfml.readTimeout=120).
Players on the modded backend need the same mods in their launcher, so the lobby should tell them before sending them over.
The errors you will see and what they mean
- "If you wish to use IP forwarding, please enable it in your Bungeecord config as well!": the backend expects forwarding and the proxy is not sending it, or the modes do not match. Check
player-info-forwarding-modeand the Paper block. - "This server requires you to connect with Velocity.": the backend has modern forwarding on but the player reached it without going through Velocity (or Velocity is not in
modernmode). If you see this when joining a backend directly, good: the back door is at least partly shut. - "Failed to verify username" through the proxy: a backend still has
online-mode=true. - Offline UUIDs or missing skins: forwarding is not working; the secret differs or
enabledis still false. - Read timed out when joining the modpack: raise
read-timeoutand-Dfml.readTimeoutas in step 8. - Bedrock players see "Outdated server" or "Outdated client": Geyser version vs game version; update whichever is behind.
How much RAM each piece needs
- Proxy: 1 GB is the documented starting point; with Geyser and ViaVersion on top, 2 GB is comfortable for a mid-sized network.
- Lobby: 2-4 GB; no terrain generation and few players at once.
- Survival with plugins: 6-8 GB for 30-60 players.
- Modpack: whatever the pack needs, typically 8-16 GB.
What actually limits a network is per-core CPU on each backend, not RAM: three servers on one oversold node drop TPS together. The lag guide explains how to tell.
Final checklist
- Backends:
online-mode=false,bungeecord: false, Velocity block inpaper-global.ymlwith the same secret. - Proxy:
modern, correct IP:port in[servers],trypointing at the lobby. - Backends unreachable from the internet except by the proxy (firewall or 127.0.0.1).
- LuckPerms on a shared database.
- Geyser and Floodgate on the proxy only; port 19132 open for UDP and TCP.
- Scheduled backups on every backend, not just survival.
A network is the project where having someone who has built one before helps most. If you host the servers with us, support helps you on Discord to get the proxy and forwarding working and to check the backends are not exposed; it is part of the service. If you already run a network elsewhere, migration goes one backend at a time, proxy last.