Understand what the proxy does
A proxy sits in front of your Paper servers. Players connect to it, and it decides which backend server to hand them to. Moving between servers becomes a command instead of a disconnect and a re-login.
players
│
▼
┌───────────────────┐
│ Velocity proxy │ ← the only public address
│ yourname.pulsedmc.net
└─────────┬─────────┘
┌───────┼───────┐
▼ ▼ ▼
lobby survival creative ← Paper servers, not public
You need, as separate servers in your panel:
- One Velocity server. It runs no world and barely any RAM, 512 MB is plenty.
- Two or more Paper servers. These are your actual gameplay servers.
A proxy is the right answer when you want separate gamemodes, or a lobby, or to restart one server without kicking everyone off the network. For a single survival server it adds moving parts and gives you nothing. Skip it until you actually have a second server.
Create the Velocity server
Order a small plan and set its Egg to Velocity in the Startup tab, then reinstall so it downloads the proxy jar.
Start it once and stop it again. That first boot writes the config files you're about to edit:
velocity.toml forwarding.secret plugins/ logs/
The proxy's address is what you give players and what your subdomain should point at. Your Paper servers keep their own addresses, but nobody should be connecting to them directly once this is set up.
Configure velocity.toml
Open Files → velocity.toml. The parts that matter are the forwarding mode and the server list.
bind = "0.0.0.0:25565" motd = "<gold>My Network</gold> <gray>| Now open</gray>" show-max-players = 100 online-mode = true # modern is the correct choice for Paper 1.13+ player-info-forwarding-mode = "modern" forwarding-secret-file = "forwarding.secret" [servers] lobby = "10.0.0.11:25565" survival = "10.0.0.12:25565" creative = "10.0.0.13:25565" # tried in order when a player first connects try = ["lobby", "survival"] [forced-hosts] "creative.yourname.pulsedmc.net" = ["creative"]
| Setting | What it does |
|---|---|
bind | The port players connect on. Leave it as the port your panel allocated. |
online-mode | Must stay true. The proxy is now what verifies players with Mojang. |
player-info-forwarding-mode | modern passes real UUIDs and skins to the backends, signed with your secret. |
[servers] | Name-to-address list. Names here become /server <name>. |
try | Where players land on connect, in order, falling through if one is down. |
Use the private address of each Paper server if they're on the same node, it's faster and never leaves the machine. Otherwise use the public IP:PORT from each server's console tab. If you're not sure which applies, open a ticket and we'll tell you.
Copy the forwarding secret
forwarding.secret is a random string generated on first boot. It's how a backend server knows a connection genuinely came from your proxy rather than from someone who found its address.
Open the file and copy its entire contents, one line, no quotes, no trailing spaces.
7fK2pQ9xLmR4vB8n
Anyone with this string and a backend server's address can connect as any username they like, including yours, on a server that has online-mode=false. Never paste it into a public Discord, a screenshot, or a forum post when asking for help.
Point each Paper server at the proxy
Repeat this on every backend server. Two files each.
server.properties
online-mode=false
The proxy already did the Mojang check, so the backend must not try to do it again. This is
the one situation where online-mode=false is correct, and it's only safe
because of the step below.
config/paper-global.yml
proxies:
velocity:
enabled: true
online-mode: true
secret: '7fK2pQ9xLmR4vB8n'
Setting online-mode=false without enabling Velocity forwarding leaves the server wide open, anyone who learns its address can join as anyone. The secret is what closes that door, so never do the first edit without the second.
Restart each backend, and watch for this line:
[10:02:14 INFO]: Applying Velocity modern forwarding [10:02:16 INFO]: Done (5.203s)! For help, type "help"
Test it
Start the proxy, then connect to the proxy's address only. You should land on
whichever server is first in try.
/server /server creative
/server on its own lists what's available; with a name it moves you. If you
switch worlds without your client reloading, forwarding is working correctly.
Close the back door
Your backend servers are still reachable directly, and they're now in
online-mode=false. Shut that off:
- Ask us to firewall the backends so only the proxy can reach them, open a ticket and name the servers.
- Point your public subdomain at the proxy, and don't publish the backend addresses.
- Keep a whitelist on the backends as a backstop while you're setting up.
Most networks add a lobby plugin with a compass that opens a server selector, so players never type /server at all. Install it on the lobby server, not on the proxy.
Make plugins network-aware
Each Paper server still has its own separate everything, permissions, homes, balances, unless you tell the plugins to share.
| What you want shared | How |
|---|---|
| Ranks & permissions | Point every LuckPerms install at one MySQL database in its config.yml, and turn on messaging-service so changes propagate instantly. |
| Economy | Use an economy plugin with MySQL support and share the database the same way. |
| Chat across servers | A cross-server chat plugin on the proxy, or a Paper-side one using the plugin messaging channel. |
| Bans | Run the punishment plugin on the proxy, so a ban stops the player at the door rather than on one server. |
Velocity takes its own plugin format. A Bukkit or Paper jar dropped into the proxy's plugins/ folder will not load. Check the download page says Velocity before installing it there.
Troubleshooting
"Unable to connect you to lobby" straight after joining
The proxy can't reach that backend, or the handshake was rejected.
- Is the backend actually running? Check its status dot.
- Is the address in
[servers]right, including the port? - Look at the backend's console at the moment you tried, the real reason is nearly always printed there, not on the proxy.
"If you wish to use IP forwarding, please enable it in your BungeeCord config"
The backend isn't set up for Velocity forwarding. Re-check step 5 on that server:
proxies.velocity.enabled: true in
config/paper-global.yml, and
online-mode=false in server.properties.
Both, then restart.
"Your server did not send a forwarding request" / players kicked at login
The secret doesn't match. It's usually invisible whitespace, a trailing newline or a space picked up when copying. Delete the value on the backend, retype it by hand, keep it inside single quotes, and restart both ends.
Everyone shows up as a Steve skin with the wrong UUID
Forwarding is falling back to legacy mode, so real identities aren't reaching the
backends. Confirm player-info-forwarding-mode = "modern" on the proxy
and that every backend is Paper 1.13 or newer. Restart the proxy last.
Left unfixed this is worse than cosmetic, player data gets keyed to the wrong UUIDs, so inventories and permissions attach to the wrong people.
Someone joined a backend server directly and opped themselves
That's the failure mode step 6 warns about. Immediately: stop the backend, set
online-mode=true so nobody else can, clear
ops.json, and open a ticket so we can firewall it. Then
re-enable forwarding once it's only reachable from the proxy.