Skip to content

Configuration Reference

This page provides a comprehensive reference for every configuration field in Passage. For a beginner-friendly introduction, see Configuration Basics.

Passage uses a layered configuration system supporting YAML, TOML, and JSON formats. The overall structure:

# Core settings
address: "0.0.0.0:25565"
timeout: 120
max_packet_length: 10000
auth_cookie_expiry: 21600
auth_secret: "your-secret"
# Optional global features
sentry: { ... }
otel: { ... }
rate_limiter: { ... }
proxy_protocol: { ... }
# Routes (per-hostname adapter configuration)
routes:
- hostname: "mc.example.net"
status: { type: fixed, ... }
authentication: { type: mojang, ... }
discovery: { type: dns_discovery, ..., actions: [...] }
localization: { type: fixed, ... }

Typestring (socket address)
Default"0.0.0.0:25565"
EnvironmentPASSAGE_ADDRESS

The network address and port that Passage binds to for incoming Minecraft client connections.

# Listen on all interfaces, standard Minecraft port
address: "0.0.0.0:25565"
# Listen on specific interface
address: "192.168.1.100:25565"
# Use custom port
address: "0.0.0.0:25566"

Typeinteger (seconds)
Default120
EnvironmentPASSAGE_TIMEOUT

Maximum time in seconds to wait for client responses during the connection flow. If the client does not respond within this time, the connection is dropped with a timeout message.

timeout: 120 # 2 minutes (default)
timeout: 60 # shorter for high-performance scenarios
timeout: 300 # longer for slow connections

Typeinteger (bytes)
Default10000
EnvironmentPASSAGE_MAX_PACKET_LENGTH

The maximum packet size in bytes that Passage will accept. Packets exceeding this size are rejected. The default of 10,000 bytes is sufficient for normal Minecraft handshake and login packets.

max_packet_length: 10000

Typeinteger (seconds)
Default21600 (6 hours)
EnvironmentPASSAGE_AUTH_COOKIE_EXPIRY

How long authentication cookies remain valid in seconds. When a player connects with a valid cookie, Passage can skip the Mojang authentication step. See Authentication Cookies for details.

auth_cookie_expiry: 21600 # 6 hours (default)
auth_cookie_expiry: 3600 # 1 hour (more frequent re-auth)

Typeinteger (seconds, optional)
Default20
EnvironmentPASSAGE_SYSTEM_OBSERVER_INTERVAL

The interval in seconds at which system metrics (CPU, memory, swap) are observed and reported via OpenTelemetry. Set to null to disable system metric collection.


Typestring (optional)
Defaultnull (disabled)
EnvironmentPASSAGE_AUTH_SECRET

Secret key for signing authentication cookies (HMAC-SHA256). If not set, authentication cookies are disabled and players must authenticate with Mojang on every connection.

Recommended approach — use a separate secret file:

Terminal window
# Generate a secret
openssl rand -base64 32 > config/auth_secret
# Or specify custom path via environment variable
export AUTH_SECRET_FILE=/run/secrets/passage-auth

The AUTH_SECRET_FILE environment variable (default: config/auth_secret) points to a plain text file whose entire contents become the auth_secret value.


Typeobject (optional)
Enabled byPresence of the section
Environment prefixPASSAGE_RATE_LIMITER_

Per-IP connection rate limiting. If omitted, rate limiting is disabled.

FieldTypeDefaultDescription
durationinteger (seconds)60Time window for counting connections.
limitinteger60Maximum connections allowed per IP within the time window.
rate_limiter:
duration: 60 # 60-second window
limit: 60 # max 60 connections per IP per minute

Behavior: If an IP exceeds limit connections within duration seconds, subsequent connections are rejected until the window expires.

Tuning guidelines:

Scenariodurationlimit
Strict (DDoS protection)6030
Balanced (default)6060
Permissive (shared IPs)120200

Typeobject (optional)
Enabled byPresence of the section
Environment prefixPASSAGE_PROXY_PROTOCOL_

PROXY protocol support for preserving real client IP addresses when Passage is behind a load balancer. If omitted, PROXY protocol is disabled.

FieldTypeDefaultDescription
allow_v1booleantrueAccept PROXY protocol v1 (text) headers.
allow_v2booleantrueAccept PROXY protocol v2 (binary) headers.
proxy_protocol:
allow_v1: true
allow_v2: true

When to enable:

  • Behind HAProxy with send-proxy or send-proxy-v2
  • Behind AWS Network Load Balancer (NLB) with proxy protocol enabled
  • Behind NGINX with proxy_protocol configured
  • Behind other PROXY protocol-compatible load balancers

Typeobject (optional)
Enabled byPresence of the section
Environment prefixPASSAGE_SENTRY_

Error tracking with Sentry. The release version is automatically inferred from the build. If omitted, Sentry is disabled.

FieldTypeDefaultDescription
debugbooleanfalseEnable Sentry SDK debug logging.
environmentstring""Environment tag for Sentry events (e.g., "production", "staging").
addressstring""Sentry DSN (Data Source Name) URL.
sentry:
debug: false
environment: "production"
address: "https://examplePublicKey@o0.ingest.sentry.io/0"

Typeobject
Environment prefixPASSAGE_OTEL_

OpenTelemetry configuration for traces, metrics, and logs. Each signal type (traces, metrics, logs) has its own endpoint and can be enabled independently.

FieldTypeDefaultDescription
environmentstring""Environment label added to all telemetry data.
tracesobject (optional)nullTraces endpoint configuration.
metricsobject (optional)nullMetrics endpoint configuration.
logsobject (optional)nullLogs endpoint configuration.

Each endpoint object has:

FieldTypeDefaultDescription
addressstring""OTLP HTTP/protobuf endpoint URL.
tokenstring""Base64-encoded basic auth token.
otel:
environment: "production"
traces:
address: "https://otlp-gateway.grafana.net/otlp/v1/traces"
token: "base64_encoded_token"
metrics:
address: "https://otlp-gateway.grafana.net/otlp/v1/metrics"
token: "base64_encoded_token"
logs:
address: "https://otlp-gateway.grafana.net/otlp/v1/logs"
token: "base64_encoded_token"

Generating a token:

Terminal window
echo -n "user:password" | base64

Supported backends: Grafana Cloud, Datadog, New Relic, Honeycomb, or any OTLP-compatible collector.

See Observability for detailed setup guides.


Typearray of route objects
Default[] (empty)

Routes define per-hostname adapter configurations. When a player connects, Passage matches the connection’s hostname against each route’s hostname regex pattern and uses the first match.

FieldTypeDefaultDescription
hostnamestring (regex)""Regex pattern to match the server hostname from the client handshake.
statusStatusAdapterfixedServer list status configuration.
authenticationAuthenticationAdaptermojangPlayer authentication configuration.
discoveryDiscoveryAdapterfixed_discoveryBackend server discovery and action pipeline.
localizationLocalizationAdapterfixedDisconnect message localization.
routes:
- hostname: "mc\\.example\\.net"
status:
type: fixed
name: "My Network"
authentication:
type: mojang
discovery:
type: fixed_discovery
targets:
- identifier: "lobby-1"
address: "10.0.1.10:25565"
localization:
type: fixed
default_locale: "en"

Selected via type within routes[].status. See Status Adapter for detailed documentation.

Static server status from configuration.

FieldTypeDefaultDescription
namestring"Passage"Server name in the server list.
descriptionstring (optional)"\"Minecraft Server Transfer Router\""MOTD as JSON text component.
faviconstring (optional)Passage logoBase64-encoded PNG (data:image/png;base64,...).
enforces_secure_chatboolean (optional)trueWhether secure chat is enforced.
preferred_versioninteger769 (1.21.4)Protocol version shown to clients.
min_versioninteger0Minimum supported protocol version. 0 = no minimum.
max_versioninteger1000Maximum supported protocol version.
status:
type: fixed
name: "My Network"
description: "{\"text\":\"Welcome!\",\"color\":\"gold\"}"
enforces_secure_chat: true
preferred_version: 769
min_version: 766
max_version: 1000

Fetches status from an HTTP endpoint with caching.

FieldTypeDefaultDescription
addressstring"http://localhost:8080"HTTP endpoint URL.
cache_durationinteger (seconds)60Cache duration. Must be greater than zero.
status:
type: http
address: "https://api.example.com/minecraft/status"
cache_duration: 30

Fetches status via a custom gRPC service.

FieldTypeDefaultDescription
addressstring""gRPC service endpoint URL.
status:
type: grpc
address: "http://status-service:50051"

Selected via type within routes[].authentication. See Authentication Adapter for detailed documentation.

TypeDescription
mojangStandard Mojang/Microsoft authentication (default).
disabledNo authentication. For testing only.
fixedFixed player profile for all connections.
grpcCustom authentication via gRPC service.

The discovery section has two parts: a discovery adapter (provides the initial target list) and an actions pipeline (transforms the list). The adapter type is set via type, and actions are listed in actions[].

See Target Discovery and Discovery Actions for detailed documentation.

Static target list from configuration.

FieldTypeDefaultDescription
targetsarray[]List of backend server targets.

Each target:

FieldTypeDefaultDescription
identifierstringrequiredUnique server identifier.
addressstringrequiredSocket address (host:port).
priorityinteger0Priority (lower = preferred).
metamap{}Key-value metadata.
discovery:
type: fixed_discovery
targets:
- identifier: "lobby-1"
address: "10.0.1.10:25565"
meta:
type: "lobby"
players: "15"

Discovers targets via DNS SRV or A/AAAA records with periodic refresh.

FieldTypeDefaultDescription
domainstring""DNS domain to query.
refresh_intervalinteger (seconds)30How often to re-query DNS.
record_typestring"srv"Record type: "srv" or "a".
portinteger25565Default port (only for record_type: a).
# SRV records
discovery:
type: dns_discovery
domain: "_minecraft._tcp.servers.example.net"
record_type: srv
refresh_interval: 30
# A/AAAA records
discovery:
type: dns_discovery
domain: "mc.example.net"
record_type: a
port: 25565
refresh_interval: 30

Discovers game servers via Agones GameServerAllocation in Kubernetes.

FieldTypeDefaultDescription
namespacestring (optional)nullKubernetes namespace. null = search all namespaces.
selectorsarray[]GameServerAllocation selector templates.
prioritiesarray[]Priority templates for allocation.
schedulingstring (optional)nullAgones scheduling strategy.
metadataobject (optional)nullMetadata template for allocation.
backoffobjectsee belowExponential backoff configuration.

Template variables (replaced in string fields if they exactly match):

  • {{ .Client.ProtocolVersion }} — client protocol version
  • {{ .Client.ServerAddress }} — server address from handshake
  • {{ .Client.ServerPort }} — server port from handshake
  • {{ .Client.Address }} — client IP (with optional proxy protocol)
  • {{ .Request.TraceId }} — OpenTelemetry trace ID

Backoff configuration:

FieldTypeDefaultDescription
initial_secsinteger2Wait time for first retry.
max_secsinteger60Maximum wait time between retries.
max_attemptsinteger10Maximum retry attempts.
factorfloat2.0Multiplicative backoff factor.
jitterfloat0.1Random jitter added (seconds).

Dynamic discovery via a custom gRPC service.

FieldTypeDefaultDescription
addressstring""gRPC service endpoint URL.
discovery:
type: grpc_discovery
address: "http://discovery-service:50051"

An optional array of actions that process the discovered target list sequentially. See Discovery Actions for the full reference.

Available action types: meta_filter, player_allow_filter, player_block_filter, player_fill_strategy, grpc.

discovery:
type: dns_discovery
domain: "servers.example.net"
record_type: srv
actions:
- type: meta_filter
rules:
- key: "status"
op: equals
value: "online"
- type: player_fill_strategy
field: "players"
max_players: 50

Selected via type within routes[].localization. See Localization for detailed documentation.

Static disconnect messages from configuration.

FieldTypeDefaultDescription
default_localestring"en_US"Default locale for unknown clients.
messagesmap6 built-in localesLocale-specific messages.
warn_unknown_keysbooleantrueWarn about unrecognized message keys in logs.

Default message keys:

KeyWhen shown
disconnect_timeoutConnection timed out (keep-alive timeout).
disconnect_no_targetNo backend server available.
disconnect_unauthenticatedAuthentication failed.

Messages use Minecraft JSON text component format:

localization:
type: fixed
default_locale: "en"
messages:
en:
locale: "English"
disconnect_timeout: '{"text":"Disconnected: Connection timed out"}'
disconnect_no_target: '{"text":"Disconnected: No server available"}'
disconnect_unauthenticated: '{"text":"Disconnected: Authentication failed"}'
de:
locale: "Deutsch"
disconnect_timeout: '{"text":"Verbindung getrennt: Zeitüberschreitung"}'
disconnect_no_target: '{"text":"Verbindung getrennt: Kein Server verfügbar"}'
disconnect_unauthenticated: '{"text":"Verbindung getrennt: Authentifizierung fehlgeschlagen"}'

Delegates localization to a custom gRPC service.

FieldTypeDefaultDescription
addressstring""gRPC service endpoint URL.

A production-ready configuration with DNS discovery, rate limiting, and observability:

# yaml-language-server: $schema=./schema.json
address: "0.0.0.0:25565"
timeout: 120
rate_limiter:
duration: 60
limit: 60
proxy_protocol:
allow_v1: true
allow_v2: true
sentry:
environment: "production"
address: "https://examplePublicKey@o0.ingest.sentry.io/0"
otel:
environment: "production"
traces:
address: "https://otlp-gateway.grafana.net/otlp/v1/traces"
token: "base64_token"
metrics:
address: "https://otlp-gateway.grafana.net/otlp/v1/metrics"
token: "base64_token"
routes:
- hostname: "mc\\.example\\.net"
status:
type: http
address: "https://example.net/status"
cache_duration: 30
authentication:
type: mojang
server_id: ""
discovery:
type: dns_discovery
domain: "servers.example.net"
record_type: srv
actions:
- type: meta_filter
name: "server-filter"
rules:
- key: "status"
op: equals
value: "online"
- type: player_fill_strategy
name: "player-fill"
field: "players"
max_players: 50
localization:
type: fixed
default_locale: "en"

Passage uses a layered configuration system. Upper layers override lower layers:

  1. Environment variables (highest priority) — format: PASSAGE_<FIELD> with _ as separator
  2. Auth secret file — sets only auth_secret (default path: config/auth_secret)
  3. Configuration file — your deployment config (default path: config/config)
  4. Default values (lowest priority) — built into Passage

Override any configuration value:

Terminal window
export PASSAGE_ADDRESS="0.0.0.0:25565"
export PASSAGE_TIMEOUT=120
export PASSAGE_RATE_LIMITER_DURATION=60
export PASSAGE_RATE_LIMITER_LIMIT=100

Change the environment variable prefix:

Terminal window
export ENV_PREFIX=MYAPP
export MYAPP_ADDRESS="0.0.0.0:25565"

Passage auto-detects the format from the file extension:

Terminal window
CONFIG_FILE=config/config.yaml passage # YAML
CONFIG_FILE=config/config.toml passage # TOML
CONFIG_FILE=config/config.json passage # JSON