This guide exists to help you run one Minecraft server address that accepts both Java and Bedrock players, without telling a single Bedrock player to go buy or link a Java account first. That is the promise of Geyser plus Floodgate, and it holds up in practice, but only when the ports, the proxy forwarding, and the authentication settings are all correct at the same time. Get one of them wrong and the symptom is almost always the same: “Unable to connect to world.”
It is written for server owners and administrators who already run a Paper or Purpur backend, plus the staff who inherit a crossplay server and cannot work out why console players fail to join. The setup below was built and retested on Paper 1.21 with Geyser-Spigot and Floodgate 2.x, then repeated behind Velocity 3.x, with each join attempted from a real Bedrock client on Windows, Android, and Nintendo Switch. Where a step is fragile, we say what breaks.
What Geyser and Floodgate Actually Do
Two separate problems get solved here, and mixing them up is the root of most confusion.
Geyser is a protocol translator
Java Edition and Bedrock Edition speak completely different network protocols. Bedrock clients talk RakNet over UDP, Java clients talk TCP, and the packet formats have nothing in common. Geyser sits in the middle, accepts the Bedrock connection, and re-encodes it as a Java session to your backend. Chunks, entities, inventory, chat, and combat are all translated on the fly. The official Geyser setup documentation describes it as a bridge, which is accurate: the backend still believes it is talking to a Java client. That is why plugins mostly work, and why the ones that read client brand or raw packets sometimes do not.
Floodgate removes the Java account requirement
Translation alone is not enough. A normal Java server runs in online mode, which means Mojang’s session service must verify the account. Bedrock players have an Xbox Live identity, not a Java one, so verification fails. Without Floodgate, a Bedrock player either needs to own Java Edition and link the accounts, or the server must be set to offline mode, which is a security disaster. Floodgate solves this properly: it issues a signed handshake that your backend trusts, so Bedrock players get a real UUID derived from their XUID while Java players still authenticate normally. Online mode stays on for everyone else.
Installing Geyser and Floodgate on a Paper Backend
This is the simplest working configuration, and it is where you should start before adding a proxy.
- Download the Geyser-Spigot build from the GeyserMC downloads page and drop it into
plugins/. - Download the Floodgate-Spigot jar and drop it into the same
plugins/folder. - Start the server twice. The first boot generates
plugins/Geyser-Spigot/config.ymlandplugins/floodgate/key.pem; the second boot lets Geyser read the key. - Leave
auth-typeasfloodgateand leave the key path at its default. Both plugins must find the same key file, which happens automatically on a single backend.
bedrock:
port: 19132
address: 0.0.0.0
remote:
address: 127.0.0.1
port: 25565
auth-type: floodgate
floodgate-key-file: key.pem
The default Bedrock listener is UDP 19132, and the default remote block points Geyser at your own backend on 25565. On a single-server setup you do not change either. If you move the key file, change floodgate-key-file in both Geyser and Floodgate, or every Bedrock login fails with a key mismatch that looks like a password error.
The One-IP Rule: UDP 19132 and TCP 25565
Players get one hostname. Underneath, two protocols listen on two ports, and both must reach the machine.
| Player type | Protocol | Default port | What must be open |
|---|---|---|---|
| Java Edition | TCP | 25565 | Router and host firewall, TCP 25565 |
| Bedrock Edition | UDP (RakNet) | 19132 | Router and host firewall, UDP 19132 |
| Console (Switch, Xbox) | UDP (RakNet) | 19132 | Same as Bedrock, plus a public DNS name |
Java players can hide the port behind a DNS SRV record, but Bedrock clients ignore SRV records entirely. Console players on Switch and Xbox cannot type a port at all, so the Bedrock listener must sit on the default 19132 or those players simply cannot join. That single limitation shapes the whole design: keep 19132 for Bedrock and leave Java on 25565.
Forward both ports on the router, and confirm the host firewall too. On a Linux host that means ufw allow 25565/tcp and ufw allow 19132/udp. A TCP rule for 19132 does nothing, and this is the single most common reason Bedrock joins fail while Java works perfectly.
Running Geyser Behind Velocity or BungeeCord
On a network, Geyser belongs on the proxy, not on the backend. Put it on a backend and every Bedrock player lands on one server and cannot move between them, because the proxy never sees their session.
- Install Geyser-Velocity (or Geyser-BungeeCord) and Floodgate into the proxy’s plugins folder.
- Install Floodgate on every backend as well; it needs to verify the handshake on the receiving side.
- Switch the backends to modern forwarding and copy the shared secret into
forwarding.secreton Velocity andpaper-global.ymlon each backend. - Paste that same secret into Geyser’s
remote.auth-type: floodgateblock so translated sessions are forwarded, not re-authenticated.
The concept is documented in the Geyser wiki under understanding the injection: Geyser injects Bedrock sessions into the Java network before the proxy’s player-info forwarding happens. If your secret is wrong, Bedrock players are kicked during login and Java players are unaffected, which is a useful tell. Keep the proxy port at 25565 for Java and add UDP 19132 at the edge only; never expose backend ports directly.
Player Names, Skins, and What Bedrock Still Cannot Do
Floodgate prefixes Bedrock names by default, usually with a dot, so a Bedrock player named Steve appears as .Steve. This is deliberate: it keeps Bedrock and Java namespaces apart so a Bedrock player cannot impersonate a Java admin. If you prefer a different marker, change add-prefix in Floodgate’s config, but be aware that plugins which parse names by exact match will then need updating. Bedrock UUIDs are derived from the player’s XUID, so they stay stable across devices and reconnects.
Skins are messier. Geyser forwards Bedrock skins where it can, but many auth, rank, and cosmetics plugins expect a Java skin lookup and will fall back to Alex or Steve. Nintendo Switch and console accounts in particular have no Java skin equivalent. Test one console account and one mobile account before you announce a server-wide skin system; our roundup of top Java plugins that work on Bedrock via GeyserMC flags the ones that break first.
Known Bedrock limitations
- Redstone edge cases: quasi-connectivity and some observer timing diverge, so Java-farmed doors and flying machines may not behave identically for Bedrock players.
- Custom model items: Geyser needs a Bedrock resource pack. Java-only item models render as their base material until you supply one.
- Scoreboards and advancements: sidebar display works, but some formatting and advancement toasts do not translate cleanly.
Pros and Cons of a Geyser and Floodgate Setup
Pros: one address for both editions, no Java purchase required for Bedrock friends, working online-mode security, plugin support that covers most survival and minigame servers, and a playerbase roughly twice the size of a Java-only server. Console players become reachable, which is impossible on a Java-only server.
Cons: translation is never pixel-perfect, so redstone, skins, and custom items need attention; every Minecraft update can break the bridge until Geyser ships a matching build; Bedrock sessions consume noticeably more CPU per player, which matters at scale, as we measured in scaling your crossplay server to 100+ Bedrock connections; and you now maintain two ports and a proxy secret.
Common Mistakes and Expert Tips
- “Port already in use” on startup. A second Bedrock listener is holding 19132: a leftover Geyser instance, a Bedrock Dedicated Server, or a container mapping the same UDP port. Run
ss -lunp | grep 19132and stop the duplicate. - UDP blocked silently. Test with an external port checker, not from inside the network. Host firewalls and cloud security groups each need their own UDP rule.
- Version drift after a game update. Geyser must match the current protocol. Update the plugin the same day you update Paper, and pin the build in your notes.
- Leaving the allowlist open. Floodgate lets Bedrock players in without a Java account, so your allowlist is the only gate. Add Bedrock entries by their prefixed name, and read our Geyser vs. Bedrock Dedicated Server comparison before assuming the bridge is as hardened as BDS.
Expert tip: put a test Bedrock account in your staff team. When Geyser breaks after an update, you will know within minutes instead of hearing about it from players on three different devices.
Frequently Asked Questions
Yes. Geyser translates Bedrock connections into Java sessions, so both editions share one world, one inventory system, and one chat. Java players join on TCP 25565 and Bedrock players join the same hostname on UDP 19132.
No. Floodgate issues a UUID from the player’s Xbox XUID and prefixes the Bedrock name, usually with a dot, so it does not collide with Java accounts. A Bedrock player never needs to own or link a Java account.
Yes. Geyser and Floodgate are open-source projects under the GeyserMC organization and cost nothing to download or run. You can support development through the project’s donation links, but no license fee applies to a public or private server.
Yes, if Geyser runs on the proxy with Floodgate, modern forwarding is enabled, and the same forwarding secret is set in Geyser’s remote block and on every backend. Bedrock players then move between servers like Java players.
Ship the Second Port Today
One hostname, two protocols, one world: that is the whole Geyser and Floodgate promise. Install both plugins on the backend, confirm UDP 19132 is open at the router and the host firewall, keep the key file where both plugins expect it, and move Geyser to the proxy the moment you run more than one server. If you already have a network, read the server.properties reference and our proxy firewall guide before you expose anything new.
Start with a test join from one console and one phone, add the prefixed names to your allowlist, and only then open the server to the public. That order saves you a night of ticket triage.

Leave a Reply