Geyser & Bedrock

Setting up Geyser and Floodgate so Bedrock Edition players can authenticate through mineLogin.

Overview

mineLogin accepts Minecraft: Bedrock Edition players that join through Geyser. Authentication is delegated to Floodgate. A Bedrock player is already verified against Xbox Live before reaching the proxy, so mineLogin treats the account as trusted and logs the player in automatically, with no /register and no /login.

Everything runs on the proxy. Geyser bridges the Bedrock protocol, Floodgate authenticates the player and gives them a prefixed username, and mineLogin reads the result through the Floodgate API during pre-login.

Bedrock client  β†’  Geyser  β†’  Floodgate  β†’  mineLogin  β†’  backend server
                 └────────── proxy β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Requirements

ComponentWhere it goes
Geyserproxy only (Geyser-Velocity or Geyser-BungeeCord)
Floodgateproxy only
mineLoginproxy only
mineLogin Bridgeevery backend server

Floodgate is an optional dependency of mineLogin. The plugin detects it at startup and disables Bedrock handling if it is missing, so nothing breaks when you run without it.

How mineLogin treats Bedrock players

Bedrock players take a separate path through pre-login. Knowing what it does saves a lot of guessing later.

BehaviourDetails
UsernameTaken from Floodgate, including the prefix, so Steve becomes .Steve
Unique idThe Floodgate unique id is kept. mineLogin skips its own game profile rewrite entirely
Account creationCreated automatically on first join and stored as a paid account
PasswordNever required. Login and registration commands are skipped
Default skinNot applied. The Bedrock skin delivered by Floodgate is used instead
Welcome headSkipped, because there is no Java skin to render into pixels
Address limitlimits.accounts-per-address is not enforced for Bedrock players
Java and Bedrock side by sideSteve and .Steve are two independent accounts

There is exactly one rejection case. If an account named .Steve already exists as a regular non paid account and the connecting Bedrock player has a linked Java account, the connection is refused with This user is already registered!. Unregister the conflicting account or remove the link.

Step 1: mineLogin

geyser:
  enable-bedrock-support: true

other-settings:
  min-nickname-length: 3
  max-nickname-length: 16
  nickname-allowed-regex: ^\.?[a-zA-Z0-9_]+$
OptionTypeDefaultDescription
enable-bedrock-supportBooleantrueResolve Bedrock players through the Floodgate API and apply the Bedrock login path
max-nickname-lengthInteger16Java limit. The Floodgate prefix length is added on top automatically
nickname-allowed-regexString^\.?[a-zA-Z0-9_]+$Must accept the Floodgate prefix

A Bedrock username passes validation through either of two paths:

  1. It matches nickname-allowed-regex directly, or
  2. It starts with the configured Floodgate prefix and the rest matches [a-zA-Z0-9_]+

The default regex covers the default prefix ., so a 16 character gamertag turning into a 17 character name still fits. If you change the prefix in Floodgate, update this regex to match.

Step 2: Floodgate

Edit plugins/floodgate/config.yml on the proxy.

key-file-name: key.pem
username-prefix: "."
replace-spaces: true
send-floodgate-data: false
OptionValueWhy
username-prefix"."Must be set and must not be a letter, digit or underscore, otherwise a Bedrock player can take over a Java account name
replace-spacestrueXbox gamertags may contain spaces, which are not valid in Minecraft usernames
send-floodgate-datafalseKeep it off unless Floodgate is installed on every backend server

mineLogin validates the prefix at startup and prints a warning if it is empty or alphanumeric, and another warning if nickname-allowed-regex would reject a prefixed name. Read the proxy console after the first start.

On send-floodgate-data: the bridge plugin uses the Floodgate API on the backend as a fast path to clear blindness and player hiding for Bedrock players the moment they join. Without it the same thing happens a fraction of a second later, once the proxy confirms the login. Turning the option on requires Floodgate with the same key.pem on every backend in your try list, otherwise those servers kick everyone. Leaving it off is the safer default.

Step 3: Geyser

Edit plugins/Geyser-Velocity/config.yml on the proxy.

java:
  auth-type: floodgate

advanced:
  floodgate-key-file: key.pem
  bedrock:
    use-waterdogpe-forwarding: false
    validate-bedrock-login: true
OptionValueWhy
auth-typefloodgateHands authentication to Floodgate. online and offline bypass it and break the mineLogin Bedrock path
floodgate-key-filekey.pemPicked up automatically when Floodgate runs as a plugin on the same proxy
use-waterdogpe-forwardingfalseOnly for WaterdogPE, not Velocity or BungeeCord
validate-bedrock-logintrueMust stay on. Disabling it lets anyone spoof a gamertag and disables Floodgate skins and linking

Bedrock uses UDP, so port 19132 has to allow UDP traffic through your firewall.

Step 4: Proxy

Velocity

online-mode = false
force-key-authentication = false
player-info-forwarding-mode = "modern"

BungeeCord

online_mode: false
enforce_secure_profile: false
ip_forward: true

force-key-authentication and enforce_secure_profile must be off. See Chat Signatures for the full explanation.

Step 5: Backend servers

On Paper, open config/paper-global.yml:

unsupported-settings:
  perform-username-validation: false

This is required, not optional. Paper validates incoming usernames against a Java character set that rejects the Floodgate prefix, so a Bedrock player who already passed proxy authentication gets kicked the moment they are routed to a backend. Apply it on every backend server, including the auth server.

The mineLogin Bridge itself needs no Bedrock specific configuration.

Running behind a PROXY protocol frontend

Networks behind a TCP filter such as TCPShield or Infinity-Filter usually require the proxy to accept a PROXY header:

[advanced]
haproxy-protocol = true

Geyser injects itself into the same proxy pipeline, so it has to send that header as well:

advanced:
  java:
    use-haproxy-protocol: true

Miss this and Bedrock players reach Geyser normally but the proxy drops the connection without sending a disconnect packet. The Geyser console then prints:

Player has disconnected from the Java server because of Β§rEnd of stream

Java players are unaffected, because their traffic arrives through the filter with the header already attached. The symptom looks like a Bedrock problem while the actual mismatch is between Geyser and the proxy.

Leave advanced.bedrock.use-haproxy-protocol at false unless your filter documents that it sends PROXY headers to the Bedrock UDP listener. When you do enable it, advanced.bedrock.haproxy-protocol-whitelisted-ips must list the filter ranges, otherwise Bedrock clients fail with a multiplayer services error.

Security: a proxy that accepts the PROXY protocol does not verify who sent the header. Firewall the proxy port so only the filter and localhost can reach it. Without that, anyone can spoof a client address and defeat accounts-per-address, IP bans and geolocation in mineLogin.

Verification

  1. The proxy console prints Successfully hooked into floodgate! during startup
  2. No warning about the Floodgate prefix or the nickname regex follows it
  3. A Bedrock player joins and reaches the lobby without typing anything
  4. The account appears in the database as .Nick, marked as paid, with the Floodgate unique id

For a detailed trace, enable development debugging temporarily:

debugs:
  development: true

Every Bedrock pre-login then prints a PreLoginSharedListener Geyser Debug block showing whether Floodgate was hooked, whether the player was resolved by connection and by unique id, and whether their account is linked. Turn it back off afterwards.

Troubleshooting

SymptomCauseFix
End of stream right after connectingProxy requires a PROXY header, Geyser does not send oneSet advanced.java.use-haproxy-protocol: true
Kicked for an invalid username on a backendPaper rejects the Floodgate prefixSet perform-username-validation: false
Please connect through the official GeyserGeyser and Floodgate use different key.pem filesCopy the Floodgate key, or run both as plugins on the same proxy
Warning about an invalid Floodgate prefixusername-prefix is empty or alphanumericSet it back to a non alphanumeric prefix such as .
Warning about the username regexnickname-allowed-regex rejects prefixed namesAllow the prefix, for example ^\.?[a-zA-Z0-9_]+$
Bedrock player is asked to registerFloodgate is missing, or enable-bedrock-support is offInstall Floodgate on the proxy and enable the option
This user is already registered!A non paid account holds the prefixed name and the player is linkedUnregister that account or remove the link
Bedrock player is blind for a moment on joinBridge fast path unavailableExpected without send-floodgate-data, it clears on login confirmation
Bedrock ping shows the wrong portGeyser listens on a non default portSet advanced.bedrock.broadcast-port to the port players actually connect to