setupmc.com

Configure Velocity Modern Forwarding with Paper in Docker

Match Velocity and Paper forwarding settings, protect the forwarding secret, block direct backend access, and verify that player identity reaches Paper safely.

Security
setupmc.com Team

Use the matching tool

Minecraft proxy configurator

Create a Docker Compose setup for Velocity, BungeeCord, or a custom proxy.

Open Minecraft proxy configurator

Why forwarding needs a complete security design

Velocity authenticates the public player connection. Paper runs with online-mode=false so it accepts the identity forwarded by the proxy. That backend setting is dangerous by itself: if a player can connect directly, they may be able to impersonate another account.

Modern forwarding protects the forwarded identity with a shared secret. PaperMC still recommends a firewall or equivalent network isolation because the secret is a second layer, not a replacement for blocking the backend.

Start with the Velocity Docker Compose setup if proxy and backend are not running yet.

Required state on the proxy

Stop the stack before editing configuration:

docker compose down

In proxy/velocity.toml, configure:

online-mode = true
player-info-forwarding-mode = "modern"
forwarding-secret-file = "forwarding.secret"

Velocity's online-mode=true keeps Mojang/Microsoft account authentication at the edge. The modern format is intended for Minecraft 1.13 and newer and is supported directly by current Paper releases.

Read the value from proxy/forwarding.secret without putting it into a command line, Git commit, screenshot, or support message. If the file does not exist, start Velocity once, let it generate the configuration, and stop it again.

Required state on Paper

The backend must already have started once so lobby/config/paper-global.yml exists.

First, set this in lobby/server.properties:

online-mode=false

Then edit lobby/config/paper-global.yml:

proxies:
  velocity:
    enabled: true
    online-mode: true
    secret: "replace-with-the-exact-forwarding-secret"

The Paper online-mode value under proxies.velocity must match the proxy's online-mode. It does not replace server.properties; the two fields describe different sides of the forwarded authentication flow.

If you previously used legacy BungeeCord forwarding, disable it in spigot.yml:

settings:
  bungeecord: false

Do not enable modern and legacy forwarding together. Velocity supports one forwarding mode for the connection path.

Keep the backend private

For backends in the same Compose project, omit ports entirely:

services:
  proxy:
    ports:
      - "25565:25577"
    networks: [minecraft]

  lobby:
    networks: [minecraft]

networks:
  minecraft: {}

Velocity reaches lobby:25565 inside Docker. The Paper service does not need a host port. Verify the resolved configuration instead of trusting indentation:

docker compose config
docker compose port proxy 25577
docker compose port lobby 25565

The first command should show the proxy mapping. The last command should show no published backend mapping.

If proxy and backend live on different physical hosts, a shared Compose network does not exist. Restrict the Paper port at the host/provider firewall to the proxy source address or carry the traffic through a private encrypted network. Never expose an offline-mode backend to the general internet.

Restart and verify identity forwarding

Start the network and watch both log streams:

docker compose up -d
docker compose logs -f proxy lobby

Join through the public proxy address. A successful test has all of these properties:

  • Velocity authenticates the Java account.
  • Paper accepts the connection without a forwarding error.
  • The backend sees the player's real UUID, skin, and address information supplied by Velocity.
  • A direct connection to the backend host port is impossible.
  • Restarting both containers does not change the secret or disable forwarding.

Test with a non-operator account before considering the network ready. An operator login can hide permission and routing mistakes.

Rotate an exposed secret

If the secret appeared in Git, logs, chat, or a screenshot, assume it is compromised:

  1. Stop Velocity and every backend.
  2. Replace proxy/forwarding.secret with a new long random value.
  3. Put the same value into every backend's Paper configuration.
  4. Confirm backend ports are still private.
  5. Restart the entire network and test a real login.

Changing only one side causes intentional login failures. Rotate as one controlled operation.

Troubleshooting

Message or symptomCauseFix
This server requires you to connect with VelocityPaper expects modern forwarding but Velocity does not send itSet proxy mode to modern and restart both sides
Login fails after secret rotationProxy and Paper secrets differCopy the exact new value to every backend
UUIDs or skins are wrongLegacy/no forwarding is still activeDisable Bungee forwarding and verify the modern configuration
Direct backend login succeedsHost port or firewall still exposes PaperRemove mapping and close external access immediately
Proxy cannot reach Paper at allDocker service/network/port mismatchUse the backend connection runbook

Next steps

Frequently asked questions

Short answers to the questions that usually come up while working through this topic.