Configuration
Complete reference for proxy.toml and plugins.toml, with validation and reload behaviour.
The proxy reads three files from its configuration directory (./config unless --config says otherwise): proxy.toml and plugins.toml, described here, and backends.toml, described in Backends and routing. Missing files are created with commented defaults on startup. A key you leave out takes the default listed below.
Validation#
Every file is validated before the proxy opens a port. The first problem found stops startup with an error of the form <file>: <key> <problem>, and the exit code is 1. For example:
config/proxy.toml: network.port is outside its integer range
config/proxy.toml: runtime requires low-water-bytes < high-water-bytes < session-buffer-bytes
config/proxy.toml: network.dual-stack requires an IPv6 bind address
config/proxy.toml: unknown is unknownA key with the wrong type reports has the wrong type, a table where a value belongs must be a table, and a misspelled key is unknown. Nothing is ignored silently.
Hot reload#
The console command reload, the SIGHUP signal (Linux and macOS) and, if enabled, file watching re-read the configuration directory. Only the contents of backends.toml (backends, default route, forced hosts) and the plugins are applied. If anything in proxy.toml or plugins.toml differs from what is running, the reload is refused as a whole and nothing changes:
Reload rejected, nothing changed: changing [network], [logging] requires a restartA file that fails validation is also refused and the running configuration stays. Sessions already in progress keep the routing they started with; new connections use the new one.
proxy.toml#
[network]#
Public listener and authentication.
| Key | Type | Default | Meaning |
|---|---|---|---|
bind |
string | "0.0.0.0" |
Literal IPv4 or IPv6 address to listen on. Hostnames are rejected. |
port |
integer | 25565 |
TCP port, 1 to 65535. |
dual-stack |
boolean | false |
Accept IPv4 clients on an IPv6 listener. Requires an IPv6 bind such as "::". |
online-mode |
boolean | true |
Authenticate Java players with Mojang. When false the proxy believes the name a player gives and assigns an offline UUID. |
accept-transfers |
boolean | false |
Accept clients that arrive through a server-initiated transfer. They still authenticate normally. |
prevent-client-proxy-connections |
boolean | false |
Include the player's address in the Mojang session check, so a player connecting through a VPN or proxy different from the one Mojang sees is refused. |
compression-threshold |
integer | 256 |
Packets at least this large are compressed toward clients. -1 disables compression, 0 compresses everything. Range -1 to 8388608. |
Offline mode
With online-mode = false anyone can join under any name, including an operator's. Only do it on a closed network where something else vouches for identity.
[runtime]#
Resource limits. The defaults suit most networks; raise max-sessions and the buffer budgets first if you need more players.
| Key | Type | Default | Range | Meaning |
|---|---|---|---|---|
io-loops |
integer | 2 |
1 to 64 | Threads that own sessions and move their bytes. |
workers |
integer | 4 |
1 to 64 | Separate pool for slow work: DNS lookups and Mojang authentication. |
max-sessions |
integer | 4096 |
1 to 65536 | Simultaneous connections. Also shown as the player maximum in the server list. |
max-pending-work |
integer | 256 |
1 to 65536 | Queue length of the worker pool. |
max-buffered-bytes |
integer | 268435456 |
4096 to 16 GiB | Global budget for retained network buffers. |
session-buffer-bytes |
integer | 16777216 |
4096 to 16 GiB | Buffer ceiling for one session. Must not exceed max-buffered-bytes. |
high-water-bytes |
integer | 4194304 |
1 to 16 GiB | A session's reads pause above this many queued bytes. |
low-water-bytes |
integer | 2097152 |
0 to 16 GiB | Reads resume below this. |
handshake-timeout-ms |
integer | 10000 |
1 to 300000 | Deadline values are in milliseconds. |
login-timeout-ms |
integer | 30000 |
1 to 300000 | Whole login, including authentication and connecting to a backend. |
connect-timeout-ms |
integer | 10000 |
1 to 300000 | One attempt to reach a backend. |
read-timeout-ms |
integer | 30000 |
1 to 300000 | Silence from a peer before the session is closed. |
write-timeout-ms |
integer | 10000 |
1 to 300000 | A peer that does not accept queued data. |
The three water marks must satisfy low-water-bytes < high-water-bytes < session-buffer-bytes.
[admission]#
Token buckets that limit new connections, both for the whole proxy and for each source address. See Operations.
| Key | Type | Default | Range | Meaning |
|---|---|---|---|---|
global-rate |
integer | 200 |
1 to 1000000 | Sustained connection attempts per second, all origins together. |
global-burst |
integer | 400 |
1 to 1000000 | Bucket capacity for the global limit. |
origin-rate |
integer | 10 |
1 to 1000000 | Sustained attempts per second from one IP address. |
origin-burst |
integer | 20 |
1 to 1000000 | Bucket capacity for one address. |
max-origins |
integer | 65536 |
1 to 1000000 | Addresses tracked at once. When the table is full, new addresses are rejected until idle entries expire. |
origin-expiry-ms |
integer | 60000 |
1000 to 3600000 | How long an idle address is remembered. |
[forwarding]#
Identity of this proxy toward backends that use forwarding = "basalt". See Forwarding.
| Key | Type | Default | Meaning |
|---|---|---|---|
proxy-id |
string | "proxy" |
Name this proxy signs into its forwarding responses, 1 to 64 bytes. |
key-file |
string | ".basalt/forwarding.key" |
Path of the private Ed25519 key, up to 4096 bytes. Created on first use. |
[logging]#
| Key | Type | Default | Meaning |
|---|---|---|---|
level |
string | "info" |
trace, debug, info, warn or error. |
file |
boolean | true |
Mirror the console into .basalt/logs/latest.log. |
keep-days |
integer | 14 |
Days of archived logs to keep, 0 to 3650. 0 keeps them forever. |
color |
string | "auto" |
auto (only on a terminal), always or never. |
[bedrock]#
See Bedrock and versions.
| Key | Type | Default | Meaning |
|---|---|---|---|
enabled |
boolean | false |
Open the Bedrock Edition UDP listener. |
port |
integer | 19132 |
UDP port, 1 to 65535. |
motd |
string | "Basalt Proxy" |
Text in the Bedrock server list, 1 to 64 bytes, without ;. |
language |
string | "" |
Path to a Minecraft server jar or to an en_us.json file, used to turn translatable messages from the backend (join and leave lines, death messages) into text for Bedrock players. Empty keeps the raw keys. Nothing is downloaded. |
delegate |
boolean | false |
Let a backend with forwarding = "basalt" serve Bedrock players itself over the session envelope, with the proxy relaying. |
[reload]#
| Key | Type | Default | Meaning |
|---|---|---|---|
watch-files |
boolean | false |
Reload by itself when a file in the configuration directory (or, with plugins on, the plugins directory) changes and has stopped changing. |
interval-ms |
integer | 2000 |
How often to look, 250 to 600000. |
A watched change that does not validate is reported in the log and the running configuration stays. It behaves like the reload command, so a change to anything but backends.toml is refused.
[translation]#
| Key | Type | Default | Meaning |
|---|---|---|---|
mode |
string | "auto" |
auto: a capable Basalt Server translates for older clients itself, otherwise the proxy translates where it has a verified route. proxy: the proxy always translates. off: client and backend must speak the same protocol. |
plugins.toml#
Controls the Lua plugin host. Plugins covers writing them; this file only decides whether they run and what they may do.
| Key | Type | Default | Meaning |
|---|---|---|---|
enabled |
boolean | false |
Load plugins at all. |
directory |
string | "plugins" |
Folder with plugin packages (.bppkg) or unpacked plugins, each with a plugin.toml. |
database |
string | ".basalt/proxy.db" |
The proxy's own SQLite file for plugin data. It is state, not configuration. |
instructions-per-turn |
integer | 250000 |
Lua instruction budget for one run of a handler, 1000 to 1000000000. |
memory-mib |
integer | 32 |
Ceiling for one plugin's Lua memory, 1 to 1024. |
queue-size |
integer | 256 |
Events waiting for the plugin thread, 1 to 65536. When full, the newest event is dropped and counted. |
operators |
array of strings | none | Player names allowed to run plugin commands that declare a permission. Matching ignores case. |
[allow] |
table | empty | Per plugin id, the powers granted beyond logging, listening, registering commands and reading the server list. |
[allow] maps a plugin id to a list drawn from commands (run console commands), network and packets. Any other name is a validation error. A plugin whose plugin.toml asks for more than is granted here does not load. Plugin data needs storage = true or players_data = true in the plugin's own manifest and no grant.
enabled = true
operators = ["Steve"]
[allow]
my_plugin = ["commands"]Plugin failures stay contained
A handler that exhausts its instruction budget or memory ceiling disables its plugin until the next reload. The proxy and other plugins keep running.