Skip to content

Getting Started

This guide will walk you through setting up Passage for the first time. By the end, you’ll have a working Minecraft network entry point that authenticates and routes players to backend servers.

Before you begin, make sure you have:

  • A Minecraft backend server running version 1.20.5 or higher
  • Docker installed (recommended), or
  • A Linux/macOS/Windows server for binary deployment
  • Basic knowledge of TOML configuration files
  1. Create Configuration Directory

    Terminal window
    mkdir -p passage/config
    cd passage
  2. Create Configuration File

    Create config/config.toml with your backend server details:

    config/config.toml
    # Bind address for player connections
    address = "0.0.0.0:25565"
    # Connection timeout in seconds
    timeout = 120
    # Server status configuration
    [status]
    adapter = "fixed"
    [status.fixed]
    name = "My Minecraft Network"
    description = "\"Welcome to my server!\""
    # Target discovery - where to send players
    [target_discovery]
    adapter = "fixed"
    [[target_discovery.fixed.targets]]
    identifier = "lobby-1"
    address = "10.0.1.10:25565" # Replace with your backend server IP
    meta = { type = "lobby" }
    # Target strategy - how to select servers
    [target_strategy]
    adapter = "fixed"
    # Localization
    [localization]
    default_locale = "en_US"
  3. Start Passage

    Terminal window
    docker run -d \
    --name passage \
    -p 25565:25565 \
    -v $(pwd)/config:/app/config \
    ghcr.io/scrayosnet/passage:latest
  4. Test Connection

    Open Minecraft (version 1.20.5+) and add a server:

    • Server Address: localhost:25565 (or your server IP)
    • Server Name: My Minecraft Network

    You should see your configured MOTD and be able to connect!

  5. Check Logs

    Terminal window
    # View real-time logs
    docker logs -f passage
    # Expected output:
    # [INFO] Passage starting on 0.0.0.0:25565
    # [INFO] Status adapter: fixed
    # [INFO] Target discovery adapter: fixed
    # [INFO] Target strategy adapter: fixed

🎉 Congratulations! You now have Passage running and routing players to your backend server.

Let’s break down what each section does:

address = "0.0.0.0:25565"
timeout = 120
  • address: The IP and port Passage listens on for player connections
    • 0.0.0.0 means accept connections from any network interface
    • 25565 is the default Minecraft port
  • timeout: How long (in seconds) to wait for a player response before disconnecting
[status]
adapter = "fixed"
[status.fixed]
name = "My Minecraft Network"
description = "\"Welcome to my server!\""

The Status Adapter provides the server list information (MOTD) that players see:

  • name: Server name in the multiplayer list
  • description: MOTD message (must be JSON text or quoted string)
[target_discovery]
adapter = "fixed"
[[target_discovery.fixed.targets]]
identifier = "lobby-1"
address = "10.0.1.10:25565"
meta = { type = "lobby" }

Target Discovery finds available backend servers:

  • identifier: Unique name for this server
  • address: Network address (IP:port) to transfer players to
  • meta: Custom key-value data (used by strategy adapters)

You can add multiple targets:

[[target_discovery.fixed.targets]]
identifier = "lobby-1"
address = "10.0.1.10:25565"
meta = { type = "lobby", players = "15" }
[[target_discovery.fixed.targets]]
identifier = "survival-1"
address = "10.0.2.10:25565"
meta = { type = "survival", players = "42" }
[target_strategy]
adapter = "fixed"

Target Strategy decides which server to send each player to:

  • fixed: Always chooses the first available target (simple, predictable)

For more advanced routing (like load balancing), see Player Fill Strategy.

[localization]
default_locale = "en_US"

Controls the language for disconnect messages and other text sent to players.

Before connecting, verify the status endpoint:

Terminal window
# If you have mcrcon or mcstatus installed
mcstatus localhost:25565 status
# Expected output:
# version: v1.21.4 (protocol 769)
# description: Welcome to my server!
# players: 0/100
  1. Open Minecraft (1.20.5+)
  2. Add server: localhost:25565
  3. Join the server
  4. You should be transferred to your backend server

Watch Passage logs during connection:

Terminal window
docker logs -f passage

Expected log flow:

[INFO] Accepted connection from 192.168.1.100:54321
[INFO] Player "Steve" authenticated with Mojang
[INFO] Selected target: lobby-1 (10.0.1.10:25565)
[INFO] Transferred player "Steve" to lobby-1
[INFO] Connection closed

Symptoms: Connection times out or “Connection refused”

Solutions:

  1. Check Passage is running: docker ps | grep passage
  2. Verify port is listening: netstat -tuln | grep 25565
  3. Check firewall allows port 25565: sudo ufw allow 25565/tcp
  4. Ensure backend server is accessible from Passage’s network

Issue: “Outdated client!” or “Outdated server!”

Section titled “Issue: “Outdated client!” or “Outdated server!””

Symptoms: Minecraft shows version mismatch error

Solutions:

  • Ensure your Minecraft client is 1.20.5 or higher
  • Verify your backend server supports the client version
  • Check preferred_version in config matches your server

Issue: Player connects but immediately disconnects

Section titled “Issue: Player connects but immediately disconnects”

Symptoms: Brief connection then kicked with “No available server”

Solutions:

  1. Verify backend server address is correct in config.toml
  2. Test backend connectivity from Passage:
    Terminal window
    docker exec passage ping 10.0.1.10 # Replace with your IP
  3. Ensure backend server is running and accepting connections
  4. Check backend server logs for connection attempts

Symptoms: Server shows wrong name/description in multiplayer list

Solutions:

  1. Verify config.toml syntax (especially quoted JSON strings)
  2. Restart Passage after config changes:
    Terminal window
    docker restart passage
  3. Refresh server list in Minecraft (right-click server → Refresh)

Issue: Docker can’t connect to backend on localhost

Section titled “Issue: Docker can’t connect to backend on localhost”

Symptoms: Backend on same machine isn’t reachable

Solutions:

  • Docker Desktop (Mac/Windows): Use host.docker.internal instead of localhost
    address = "host.docker.internal:25565"
  • Linux: Use Docker host IP (usually 172.17.0.1)
    address = "172.17.0.1:25565"
  • Or use --network host when running Docker (Linux only)

Example 1: Multiple Lobby Servers (Load Balancing)

Section titled “Example 1: Multiple Lobby Servers (Load Balancing)”
address = "0.0.0.0:25565"
timeout = 120
[status]
adapter = "fixed"
[status.fixed]
name = "BigNetwork"
description = "\"500 players online!\""
[target_discovery]
adapter = "fixed"
[[target_discovery.fixed.targets]]
identifier = "lobby-1"
address = "10.0.1.10:25565"
meta = { type = "lobby", players = "45" }
[[target_discovery.fixed.targets]]
identifier = "lobby-2"
address = "10.0.1.11:25565"
meta = { type = "lobby", players = "38" }
[[target_discovery.fixed.targets]]
identifier = "lobby-3"
address = "10.0.1.12:25565"
meta = { type = "lobby", players = "52" }
[target_strategy]
adapter = "player_fill"
[target_strategy.player_fill]
field = "players"
max_players = 50

This configuration will fill lobbies to 50 players before moving to the next one.

For region-based routing with custom logic, you’ll need a gRPC adapter. See Custom gRPC Adapters for implementation details.

address = "0.0.0.0:25565"
timeout = 120
[status]
adapter = "http"
[status.http]
address = "http://status-service.minecraft/status"
cache_duration = 5
[target_discovery]
adapter = "agones"
[target_discovery.agones]
namespace = "minecraft"
label_selector = "game=minecraft,type=lobby"
[target_strategy]
adapter = "player_fill"
[target_strategy.player_fill]
field = "players"
max_players = 50

This discovers Minecraft lobbies running as Agones GameServers and fills them sequentially. See Kubernetes Guide for full setup.

Before asking for help, verify:

  • ✅ Minecraft client version is 1.20.5 or higher
  • ✅ Backend server version is 1.20.5 or higher
  • ✅ Backend server is running and accessible
  • ✅ Port 25565 is not blocked by firewall
  • ✅ Configuration file is valid TOML
  • ✅ Backend address is correct (not localhost if using Docker)
  • ✅ Passage logs show no errors (docker logs passage)

If you encounter issues:

  1. Check logs: docker logs passage often reveals the problem
  2. Enable debug logging: Set RUST_LOG=debug environment variable
    Terminal window
    docker run -d \
    --name passage \
    -p 25565:25565 \
    -v $(pwd)/config:/app/config \
    -e RUST_LOG=debug \
    ghcr.io/scrayosnet/passage:latest
  3. Review documentation: Many common issues are covered in specific guides
  4. Community support: Visit our GitHub Discussions
  5. Bug reports: File issues at GitHub Issues

You’ve learned:

  • ✅ How to install and run Passage with Docker
  • ✅ Basic configuration structure (status, discovery, strategy)
  • ✅ How to connect Minecraft clients to Passage
  • ✅ Common troubleshooting steps
  • ✅ Next steps for advanced features

Passage is now routing players to your backend servers with minimal overhead and maximum performance!