Proxy Setup
Configure Velocity proxy in Nimbus — adaptive forwarding, auto-patching, Via plugins, Bedrock support, MOTD, tab list, chat, and maintenance mode.
Nimbus uses Velocity as its proxy layer. The proxy sits in front of all backend servers, handling player connections, server switching, and cross-server features like tab lists and chat formatting.
How it works
When Nimbus starts, it:
- Creates a Velocity proxy instance from your proxy group config
- Auto-generates
velocity.tomlwith all backend servers listed - Deploys the nimbus-bridge plugin to the proxy
- Keeps the server list in sync as services start and stop
You never need to manually edit velocity.toml -- Nimbus manages it entirely.
Proxy group configuration
Create a proxy group in config/groups/proxy.toml:
[group]
name = "Proxy"
type = "STATIC"
software = "VELOCITY"
version = "3.4.0"
[group.resources]
memory = "512M"
max_players = 500
[group.scaling]
min_instances = 1
max_instances = 1
[group.jvm]
optimize = trueThe proxy should almost always be STATIC with a single instance. For high-traffic networks, see Multiple Proxies below.
Adaptive Forwarding Mode
Nimbus automatically determines the correct forwarding mode for your entire network. You never need to configure this manually -- it is calculated every time a service starts, based on all your group configurations.
Zero-config forwarding
This is one of the things that makes Nimbus special. In a traditional setup, you'd need to manually configure forwarding in velocity.toml, copy forwarding.secret files, patch spigot.yml or paper-global.yml, and install forwarding mods on modded servers. Nimbus does all of this automatically.
How it works
When Nimbus starts any service, it evaluates all backend groups:
- If all backend groups run Minecraft 1.13 or newer → modern forwarding (recommended, more secure)
- If any backend group runs a version older than 1.13 → legacy/BungeeCord forwarding (for compatibility)
This is recalculated dynamically. If you add a 1.12.2 group to a network that was using modern forwarding, Nimbus will automatically switch to legacy mode for all new services.
Modern forwarding (default)
Used when all backends are 1.13+. Modern forwarding uses a shared secret (forwarding.secret) to cryptographically verify that connections actually come from the proxy.
Nimbus configures this automatically for every server type:
- Velocity — Sets
player-info-forwarding-mode = "modern"invelocity.toml - Paper/Pufferfish/Purpur/Leaf — Enables velocity support in
paper-global.ymland copies the forwarding secret - Fabric — Configures FabricProxy-Lite with the secret (auto-installed)
- Forge/NeoForge — Configures proxy-compatible-forge with the secret (auto-installed)
Legacy (BungeeCord) forwarding
Used when any backend runs a pre-1.13 version. Less secure, but the only option for older servers.
Nimbus detects and configures this automatically:
- Sets
player-info-forwarding-mode = "legacy"invelocity.toml - Enables
bungeecord: truein each backend'sspigot.yml - Configures FabricProxy-Lite / proxy-compatible-forge in legacy mode for modded servers
Legacy forwarding trusts any connection claiming to be from the proxy. Make sure your backend servers are not directly accessible from the internet -- only the proxy port (25565) should be public.
Compatibility checks
Nimbus runs automatic compatibility checks when starting up. If it detects a forwarding conflict (e.g., a pre-1.13 server forcing legacy mode while a Forge server requires modern forwarding), it will warn you in the console with a clear explanation of the problem and how to fix it.
Automatic Proxy Forwarding Mods
When you create a modded server group (Fabric, Forge, or NeoForge), Nimbus automatically downloads and installs the correct proxy forwarding mod so players can connect through Velocity seamlessly. No manual mod installation needed.
| Server Software | Auto-installed Mod | Source |
|---|---|---|
| Fabric / Quilt | FabricProxy-Lite + Fabric API | Modrinth |
| Forge | proxy-compatible-forge | Modrinth |
| NeoForge 1.20.2+ | NeoForwarding | Modrinth |
| NeoForge (older) | proxy-compatible-forge | Modrinth |
This happens transparently when a service is started:
- Nimbus checks the template's
mods/directory for an existing forwarding mod - If none is found, it downloads the correct mod from Modrinth (matched to your MC version)
- The mod is configured automatically with the correct forwarding mode and secret
For Fabric servers, Nimbus also auto-installs Fabric API as a dependency, since FabricProxy-Lite requires it.
The forwarding mod configuration is patched to match the adaptive forwarding mode — if your network uses modern forwarding, the mod gets the forwarding.secret; if legacy, it gets BungeeCord mode. This is fully automatic.
Via plugins (multi-version support)
To allow players on different Minecraft versions to connect through a single proxy, Nimbus supports automatic deployment of Via plugins:
| Plugin | Purpose | Dependencies |
|---|---|---|
| ViaVersion | Allows newer clients to connect to older servers | None |
| ViaBackwards | Allows older clients to connect to newer servers | ViaVersion (auto-included) |
| ViaRewind | Extends ViaBackwards support to very old versions (1.7-1.8) | ViaBackwards |
Nimbus enforces the full dependency chain automatically during group creation and from the plugins command: selecting ViaRewind pulls in ViaBackwards, which in turn pulls in ViaVersion. Selecting ViaBackwards on its own still pulls in ViaVersion. You only need to tick the highest-level plugin you want — the required prerequisites are added for you.
Important
Via plugins are deployed only on backend servers, never on the proxy itself. This is the recommended setup for Velocity-based networks -- the proxy handles connections natively, and Via plugins on backends handle protocol translation.
Via plugins are selected during group creation (or via the plugins command) and downloaded into the group's own template plugins/ directory. You don't manage them by hand — Nimbus picks compatible versions from Hangar/Modrinth and auto-resolves dependencies.
templates/
Lobby/
plugins/
ViaVersion-<ver>.jar
ViaBackwards-<ver>.jarVelocity Auto-Patching (6-hourly updates)
Nimbus keeps your Velocity proxy up to date automatically. A background job checks the PaperMC API for new Velocity releases every 6 hours and applies updates without manual intervention.
No downtime required
Updates are downloaded and staged automatically, but only take effect on the next proxy restart. Your running proxy is never interrupted. For dynamic proxy instances, new instances automatically pick up the latest version from the updated template.
How it works
- Check — Every 6 hours (starting 60 seconds after boot), Nimbus queries the PaperMC API for the latest Velocity version
- Compare — If the latest version matches your current version, nothing happens
- Download — If a new version is found, the JAR is downloaded to the proxy template directory
- Stage — For static proxy instances, the new JAR is copied into the working directory
- Persist — The version in
config/groups/proxy.tomlis updated automatically so the change survives restarts - Notify — Events are emitted for monitoring and integrations
Events
| Event | When | Payload |
|---|---|---|
ProxyUpdateAvailable | New version detected | oldVersion, newVersion |
ProxyUpdateApplied | Download complete, JAR staged | oldVersion, newVersion |
You can listen for these events via the WebSocket API to trigger alerts, Discord notifications, or automated restart scripts.
[18:00:01] ℹ New Velocity version available: 3.4.0 → 3.5.0
[18:00:04] ℹ Downloaded Velocity 3.5.0 (12.4 MB)
[18:00:04] ℹ Updated Velocity JAR for static service 'Proxy-1' (restart to apply)
[18:00:04] ✓ Velocity updated: 3.4.0 → 3.5.0 (restart proxy to apply)If the download fails (network issue, API outage), Nimbus silently keeps the old version and retries at the next 6-hour interval. No action needed from you.
Proxy synchronization
Nimbus provides centralized configuration for tab lists, MOTD, and chat formatting that is synced to all proxy instances in real-time via the API and WebSocket events.
Configuration is split into three files in config/modules/syncproxy/:
| File | Purpose |
|---|---|
tablist.toml | Tab list header, footer, player name format |
motd.toml | Server list MOTD + maintenance mode |
chat.toml | Chat format settings |
Tab list
config/modules/syncproxy/tablist.toml:
[tablist]
header = "\n<gradient:#58a6ff:#56d4dd><bold>MY NETWORK</bold></gradient>\n"
footer = "\n<gray>Online</gray> <white>»</white> <gradient:#56d4dd:#b392f0>{online}</gradient><dark_gray>/</dark_gray><gray>{max}</gray>\n"
player_format = "{prefix}{player}{suffix}"
update_interval = 5Placeholders:
| Placeholder | Description |
|---|---|
{online} | Total players online |
{max} | Max player slots |
{player} | Player's username |
{prefix} | Player's permission group prefix |
{suffix} | Player's permission group suffix |
{server} | Current server name (e.g., Lobby-1) |
{group} | Current group name (e.g., Lobby) |
Per-player tab name overrides are also supported via the SDK:
Nimbus.setTabName(player.getUniqueId(), "<red>[RED] {player}");
Nimbus.clearTabName(player.getUniqueId());MOTD
config/modules/syncproxy/motd.toml:
[motd]
line1 = " <gradient:#58a6ff:#56d4dd:#b392f0><bold>MY NETWORK</bold></gradient>"
line2 = " <gray>» </gray><gradient:#56d364:#56d4dd>{online} players online</gradient>"
max_players = -1
player_count_offset = 0| Field | Description |
|---|---|
line1 / line2 | MiniMessage-formatted MOTD lines |
max_players | Override max player count shown (-1 = use Velocity default) |
player_count_offset | Add to the displayed online count (useful for appearance) |
Chat format
config/modules/syncproxy/chat.toml:
[chat]
format = "{prefix}{player}{suffix} <dark_gray>» <gray>{message}"
enabled = trueSet enabled = false to let another plugin handle chat formatting.
All proxy sync settings can be changed at runtime via the REST API (PUT /api/proxy/tablist, PUT /api/proxy/motd, PUT /api/proxy/chat). Changes are pushed to all proxies instantly via WebSocket.
Maintenance mode
Maintenance mode lets you block new player connections without shutting down the network. It is configured in motd.toml alongside the regular MOTD:
[maintenance]
enabled = false
motd_line1 = " <gradient:#ff6b6b:#ee5a24><bold>MAINTENANCE</bold></gradient>"
motd_line2 = " <gray>We are currently performing maintenance.</gray>"
protocol_text = "Maintenance"
kick_message = "<red><bold>Maintenance</bold></red>\n<gray>The server is currently under maintenance.\nPlease try again later.</gray>"
whitelist = []When global maintenance is enabled:
- The MOTD switches to the maintenance lines
- The version protocol shows a red "x" with the
protocol_textin the server list - New connections are blocked — non-whitelisted players receive the
kick_message - Players on the
whitelistor with thenimbus.maintenance.bypasspermission can still join
Group maintenance prevents players from joining servers of a specific group — useful when updating templates or running tests:
[maintenance.groups.BedWars]
enabled = true
kick_message = "<red>BedWars is currently under maintenance.</red>"Players trying to connect to a BedWars server will be sent back to the lobby with the kick message.
Toggle maintenance via the console or in-game:
nimbus » maintenance on
✓ Global maintenance enabled.
Players without bypass will be disconnected by the proxy.
nimbus » maintenance BedWars on
✓ Group BedWars maintenance enabled.
Players will not be able to join BedWars servers.
nimbus » maintenance add jonas
✓ Added jonas to maintenance whitelist.Or in-game with /cloud maintenance on, /cloud maintenance BedWars on, etc.
Maintenance state is also available via the REST API at GET /api/maintenance and can be toggled with POST /api/maintenance/global and POST /api/maintenance/groups/{name}.
nimbus-bridge plugin
The bridge plugin is automatically deployed to all proxy instances. It provides:
Commands
| Command | Permission | Description |
|---|---|---|
/hub, /lobby, /l | None | Send player to a lobby server |
/cloud status | nimbus.cloud.status | Network overview |
/cloud list [group] | nimbus.cloud.list | List running services |
/cloud info <service> | nimbus.cloud.info | Service details |
/cloud start <group> | nimbus.cloud.start | Start a new instance |
/cloud stop <service> | nimbus.cloud.stop | Stop a service |
/cloud restart <service> | nimbus.cloud.restart | Restart a service |
/cloud exec <service> <cmd> | nimbus.cloud.exec | Execute console command |
/cloud players | nimbus.cloud.players | Online player list |
/cloud send <player> <service> | nimbus.cloud.send | Transfer a player |
/cloud groups | nimbus.cloud.groups | List all groups |
/cloud setstate <service> <state> | nimbus.cloud.setstate | Set custom state |
/cloud reload | nimbus.cloud.reload | Reload Nimbus config |
/cloud shutdown | nimbus.cloud.shutdown | Shut down the network |
/cloud perms ... | nimbus.cloud.perms | Permission management |
/cloud maintenance ... | nimbus.cloud.maintenance | Toggle maintenance mode |
The base permission nimbus.cloud is required to use any /cloud subcommand. The /cloud command is also aliased as /nimbus.
Connection handling
- Players are automatically sent to a lobby server on connect
- Modded client routing: NeoForge/Forge/Fabric clients are automatically detected via
player.getModInfo()and routed to a server from a modded group instead of the Paper lobby. This prevents the "incompatible mods" kick that happens when NeoForge clients connect to vanilla/Paper servers - If kicked from a non-lobby server, players are redirected back to the lobby
- If no lobby is available, the player is disconnected with an error message
- Lobby servers are identified by group names starting with "Lobby" (case-insensitive)
Permission integration
The bridge integrates with Nimbus's permission system and provides:
- Automatic permission loading on player login
- Real-time permission updates via WebSocket events
- Wildcard permission matching (e.g.,
nimbus.cloud.*) - Permission cache that invalidates on disconnect
Modded Client Support (Forge / NeoForge / Fabric)
Nimbus automatically configures Velocity and routes players so that modded clients can connect to your network without any manual setup.
What happens automatically
When any backend group uses FORGE, NEOFORGE, or FABRIC software:
- Velocity config patching —
announce-forge = trueis set invelocity.tomlso Velocity advertises Forge compatibility in the server list ping. Connection and read timeouts are increased to handle large mod lists - Modded client routing — The bridge plugin detects modded clients on login (via Velocity's
ModInfoAPI) and routes them to the least-loaded server from a modded group, instead of the Paper lobby - Forwarding mods — proxy-compatible-forge or FabricProxy-Lite are auto-installed on modded backends (see Automatic Proxy Forwarding Mods)
NeoForge clients cannot join vanilla/Paper servers — they get kicked with "incompatible mods". This is a NeoForge protocol limitation, not a Nimbus bug. You need at least one NeoForge backend group for NeoForge players to connect to.
Example setup
A typical mixed network with both vanilla and modded players:
[group]
name = "Lobby"
software = "PAPER" # Vanilla players land here
version = "1.21.4"[group]
name = "ModdedLobby"
software = "NEOFORGE" # NeoForge players land here automatically
version = "1.21.1"
modloader_version = "21.1.172"Vanilla clients → Lobby-1, NeoForge clients → ModdedLobby-1. Fully automatic, no configuration needed beyond the group definitions.
The modded groups cache is refreshed automatically when the controller becomes reachable and on WebSocket reconnect. Changes to group software types take effect without a proxy restart.
Bedrock Edition Support
Nimbus supports Bedrock Edition crossplay via Geyser and Floodgate. This allows players on mobile (iOS/Android), consoles (Xbox, PlayStation, Switch), and Windows 10/11 Bedrock Edition to join your Java Edition network.
Enabling Bedrock support
Add the [bedrock] section to config/nimbus.toml:
[bedrock]
enabled = true
base_port = 19132Or enable it during the setup wizard when asked "Enable Bedrock Edition?".
What happens automatically
When Bedrock support is enabled, Nimbus:
- Downloads Geyser — Velocity plugin that translates Bedrock protocol to Java protocol
- Downloads Floodgate — Deployed to both proxy and all Paper/Purpur/Leaf/Folia backends
- Manages
key.pem— Floodgate's shared encryption key is generated on first proxy start and distributed to all services automatically - Configures Geyser — Each proxy instance gets its own UDP port and auto-generated Geyser config pointing to the correct Java port
- Allocates UDP ports — Starting from
base_port(default 19132), incrementing for each proxy instance
Architecture
Bedrock (UDP:19132) ──► Velocity + Geyser + Floodgate ──► Backends + Floodgate
Java (TCP:25565) ──► ──►Geyser runs inside the Velocity process and translates Bedrock connections into Java protocol. After translation, backend servers see all players as normal Java clients — no backend changes needed.
Ports
| Protocol | Default Port | Transport |
|---|---|---|
| Java Edition | 25565 | TCP |
| Bedrock Edition | 19132 | UDP |
Both ports must be open on your server. Bedrock uses UDP, not TCP — make sure your firewall allows UDP traffic on the Bedrock port.
Checking Bedrock status
The status command shows Bedrock support status:
nimbus » status
...
Bedrock: enabled (Geyser + Floodgate, base port 19132)The list command shows both TCP and UDP ports for proxy services:
nimbus » list
Proxy-1 Proxy ● READY 25565/19132 0 12345 1h 30mMOTD, Server Icon & Player Count
Geyser is configured to pass through the Java proxy's MOTD, player counts, and protocol name to Bedrock clients. This means Bedrock players see the same server list information as Java players — including your custom MOTD from the proxy sync configuration and the server icon.
No additional configuration is needed. The passthrough is enabled automatically in the generated Geyser config.
Load Balancer + Bedrock
The built-in TCP load balancer handles Java connections only. Bedrock UDP traffic is not load-balanced. Instead, when both the load balancer and Bedrock support are enabled:
- The first proxy instance receives the standard Bedrock port (19132) — this is the port Bedrock players connect to
- Additional proxy instances get incremented ports (19133, 19134, ...) but typically only the first one matters for Bedrock
- Java players are distributed across all proxies by the TCP load balancer as usual
This approach works well because Bedrock player counts are typically much smaller than Java. If you need full Bedrock load balancing, use an external UDP-capable load balancer (e.g., HAProxy with UDP support).
Limitations
- Modded backends — Floodgate is only deployed to Paper/Purpur/Leaf/Folia backends. Fabric/Forge/NeoForge servers do not receive Floodgate, so backend plugins won't identify Bedrock players on modded servers. Players can still connect through the proxy.
- Gameplay differences — Bedrock and Java have different combat systems, redstone behavior, and some items/blocks are mapped to the closest equivalent. See GeyserMC docs for details.
Bedrock players authenticate via Xbox Live. Their names are prefixed with . by default (e.g., .BedrockPlayer123) to avoid name collisions with Java players.
Multiple proxies
For large networks, you can run multiple Velocity proxies behind a TCP load balancer (e.g., HAProxy, nginx). Change the proxy group scaling:
[group.scaling]
min_instances = 2
max_instances = 4Each proxy instance receives the same bridge plugin and sync configuration. All proxies connect to the same Nimbus API and receive the same real-time events.
Multiple proxies require an external load balancer for Java traffic. With Bedrock enabled, each proxy instance gets its own UDP port — only the first proxy (port 19132) is typically reachable by Bedrock players unless you configure an external UDP load balancer.
Next steps
- Server Groups -- Configure backend servers
- Auto-Scaling -- Set up dynamic scaling
- Bridge Plugin -- Detailed bridge reference