Velocity
Overview
Velocity is a modern, high-performance proxy for Minecraft Java Edition, built by PaperMC. It is not a game server and has no world or player database of its own. It sits in front of one or more backend Minecraft servers that you already run, such as a hub, a survival world or a minigame lobby, and routes players between them. Your community connects to one address and moves between your servers without disconnecting.
This guide covers the deployment and use of Velocity 4.0.0 on Ubuntu 24.04 on Azure, using the SecureAnyCloud Azure Marketplace image. The image ships the independent Velocity proxy only. No Mojang or Minecraft asset of any kind is downloaded, bundled or referenced. Velocity is licensed separately (GPL-3.0) from the game it proxies for.
What you get:
- A single public entry point. Players connect to one address, and Velocity routes them to the right backend server.
- Modern player-info forwarding. Player identity and IP are forwarded to backends over Velocity's own authenticated protocol, not the legacy, spoofable BungeeCord format.
- A forwarding secret that is never shared. The secret Velocity uses to authenticate itself to backends is generated fresh, with real entropy, on this VM's first boot. It is never baked into the image and never the same across two deployments.
- online-mode enabled. Players are authenticated against Mojang by default, so usernames cannot be spoofed.
- A protocol-level health proof. The image can prove that the proxy is alive and speaking the real Minecraft wire protocol, not just that a port answers.
- 24/7 SecureAnyCloud support
Scope of this image
Velocity boots and listens standalone. On a fresh VM, the proxy starts, binds the Minecraft listener, and answers a real Minecraft Server List Ping with a valid version and MOTD response. This is the same handshake a Minecraft client uses to show a server in its multiplayer list. The image proves this automatically on every deployment (see Verifying your deployment).
The image does not claim end-to-end player routing. Routing depends on backend Minecraft servers that are entirely your own infrastructure, and this image is a single-VM proxy appliance, not a network of game servers. To complete the setup, point Velocity at your own backends in velocity.toml (see Configuring your backend servers).
License
Velocity is free software licensed under the GNU General Public License, version 3. This is upstream's license, verified from the LICENSE file at the commit this build was compiled from, not from a badge.
The image ships the license obligations with the binary:
/usr/share/doc/velocity/LICENSE: the full GPL-3.0 text./usr/share/doc/velocity/SOURCE.txt: the exact upstream build and commit the installed binary came from, a link to the corresponding source tree, and a written offer for that source.
SecureAnyCloud's own additions (the first-boot bootstrap, the Server List Ping probe and the round-trip audit) are kept in separate files under /usr/local and are themselves licensed GPL-3.0-or-later. Velocity and Minecraft are trademarks of their respective owners. SecureAnyCloud is not affiliated with or endorsed by PaperMC or Mojang Studios.
Before you start
Plan for the following:
- Recommended VM size: Standard_B2s (2 vCPU / 4 GiB). A proxy is far lighter than a game server.
- Minecraft listener: TCP 25577. This port must be reachable from the internet. The Java Edition protocol is TCP only, so there is no UDP port to open.
- SSH: port 22, restricted to your own address.
- Java runtime: OpenJDK 25, installed from the Ubuntu 24.04 archive (never Oracle JDK).
The JVM heap is capped at -Xms512M -Xmx768M, which fits comfortably within the 4 GiB of a Standard_B2s and leaves headroom for the OS. The image has no swap. Azure manages swap on the ephemeral resource disk, and the image is verified swap-free at capture time.
Network security group
The Minecraft listener is the only port that must be public. Velocity uses TCP 25577 only:
# Run from your workstation, not the VM. Replace the names with your own.
az network nsg rule create --resource-group <your-rg> --nsg-name <your-nsg> \
--name velocity-proxy-tcp --priority 1010 \
--access Allow --protocol Tcp --direction Inbound \
--source-address-prefixes Internet --destination-port-ranges 25577First boot
On first boot, the VM generates its own forwarding secret, with 256 bits of entropy from openssl rand -hex 32, before the proxy is allowed to start at all. Nothing is baked into the image: it contains no secret and no configuration beyond the shipped sample values.
The ordering is deliberate. If Velocity starts and finds no forwarding secret file, it silently generates one. That would be the wrong behaviour for an image-based appliance, because every customer VM cloned from the same captured image would share the same secret.
The image closes that gap structurally. velocity.service does not start until a bootstrap-ready marker exists, and only this VM's own first-boot script can create that marker, after it has written a real secret.
Wait a minute after the VM reports Running, then check the service:
systemctl is-active velocity-firstboot.service velocity.serviceactive activeNext, read this VM's credentials:
sudo cat /root/velocity-credentials.txt# Velocity proxy — per-VM credentials, generated at first boot.
# See: https://secureanycloud.com/stacks/velocity/ VELOCITY_FORWARDING_SECRET=<64 lowercase hex characters, unique to this VM> VELOCITY_LISTEN_PORT=25577 VELOCITY_PUBLIC_IP=<this VM's public IP>The file is 0600 root:root. Treat it like any other secret. Your backend Minecraft servers need the same value (see below) to accept connections forwarded by this proxy.
Full service log on a clean first start
sudo journalctl -u velocity.service --no-pager -n 15Started velocity.service - Velocity Minecraft proxy. main WARN Advanced terminal features are not available in this environment [INFO]: Booting up Velocity 4.0.0... [INFO]: Connections will use epoll channels, libdeflate (Linux x86_64) compression, OpenSSL 3.x.x (Linux x86_64) ciphers [INFO]: Loading localizations... [INFO]: Loading plugins... [INFO]: Loaded 1 plugins [INFO]: Listening on /[0:0:0:0:0:0:0:0]:25577 [INFO]: Done (0.84s)!Configuring your backend servers
Velocity ships with sample backend addresses. They are not real, reachable servers. Because this is a single-VM proxy appliance, only you can point it at your own infrastructure.
Review the current configuration:
sudo cat /etc/velocity/velocity.tomlThe [servers] table is where you define your own backends:
[servers]
# PLACEHOLDER — replace with your own backend server(s). lobby = "127.0.0.1:30066" try = [ "lobby" ]Edit the table to point at your real backend servers:
sudoedit /etc/velocity/velocity.toml[servers] lobby = "10.0.1.10:25565" survival = "10.0.1.11:25565" try = [ "lobby" ]Restart the proxy to apply the change:
sudo systemctl restart velocity.servicePairing your backend servers with this proxy
Configure every backend server behind Velocity to trust this proxy specifically, using the same forwarding secret that this VM generated at first boot:
- Copy the value of
VELOCITY_FORWARDING_SECRETfrom/root/velocity-credentials.txton this VM. - On each backend Paper or Velocity-aware server, set
velocity-secret-file(or the equivalent setting for your server software) to a file that contains that exact value. - Enable modern forwarding in the backend server's own configuration. For Paper, set
proxies.velocity.enabled: trueinconfig/paper-global.yml, with the same secret. - Restart the backend server.
Never type a secret of your own choosing on the backend. Always copy the value this VM generated, so both ends use the same secret.
Verifying your deployment
The image carries its own audit. It does more than check that a port is open. It confirms that the forwarding secret is unique to this VM and matches what the proxy actually loaded, and that the proxy answers a real Minecraft protocol handshake:
sudo /usr/local/sbin/velocity-roundtrip-check.shCREDENTIAL_OK: forwarding-secret is 64 hex chars, per-VM, matches the live file SLP_OK version=Velocity 4.0.0 protocol=767 motd={'color': '#09add3', 'text': 'A Velocity Proxy on sac — configure your backend servers'} players_max=500 ROUNDTRIP_OKA successful run ends with ROUNDTRIP_OK. If anything fails, the audit exits non-zero and prints the word FAIL. Failures include a missing or too-short secret file, a credentials file out of sync with the live secret, a weak or sample value, and a proxy that fails to answer a real Server List Ping.
You can also run the Server List Ping probe on its own at any time:
python3 /usr/local/lib/sac/velocity-slp-probe.py 127.0.0.1 25577Troubleshooting
velocity.service will not start. The service waits until velocity-firstboot.service has written a per-VM forwarding secret. This is deliberate, so the proxy can never start without a secret and silently generate a shared one. Check the first-boot service first:
systemctl status velocity-firstboot.service --no-pager sudo journalctl -u velocity-firstboot.service --no-pager -n 30If the first-boot service is active (exited) and the sentinel exists (ls -l /var/lib/sac/data/velocity-firstboot.done) but velocity.service still refuses to start, check the bootstrap-ready marker:
ls -l /var/lib/sac/data/velocity-bootstrap-ready
sudo systemctl status velocity.service --no-pagerPlayers cannot connect through the proxy. Confirm that the NSG allows inbound TCP 25577 (Java Edition has no UDP port). Then confirm that your backend servers are reachable from this VM and configured with the same forwarding secret:
sudo grep -A3 '^\[servers\]' /etc/velocity/velocity.tomlReplace YOUR-BACKEND-IP with the real address, then confirm that the backend is reachable from this VM:
nc -zv YOUR-BACKEND-IP 25565A player is kicked immediately after connecting. This is almost always a forwarding-secret mismatch between this proxy and the backend server that received the player. The backend rejects the forwarded player-info packet. Copy VELOCITY_FORWARDING_SECRET from /root/velocity-credentials.txt on this VM into the backend's configuration again, exactly as it appears, and restart the backend.
Check that the proxy is alive, not just that the port is open.
sudo /usr/local/sbin/velocity-roundtrip-check.shA FAIL line names exactly which check did not pass.
Support
SecureAnyCloud images come with 24/7 support. With any request, include the output of sudo /usr/local/sbin/velocity-roundtrip-check.sh and the last lines of sudo journalctl -u velocity.service --no-pager -n 50.
Velocity itself is community software maintained by PaperMC. For questions about proxy configuration, plugins and the protocol, contact the upstream project and its community.
Deploy on Azure
Launch Velocity 4.0.0 on Ubuntu 24.04 on Azure with 24/7 support from SecureAnyCloud.
View this image
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com