We recommend running the Bedrock Minecraft Server on 64-bit Intel or AMD processor machines with at least 2 cores and 1 Gb RAM.
The Linux version of the Bedrock Server requires Ubuntu 18 or later. Other distributions are not supported. Unzip the container file into an empty folder. Start the server with the following command:
LD_LIBRARY_PATH=. ./bedrock_server
The Windows version of the Bedrock Server requires either:
bedrock_server.exe file.
The server will try to read a file named server.properties. Some of these options are only read when a new world is created, while some others are read every startup. The file should contain a list with keys and values separated with an equal sign, one per line.
The following options are available. If a value as a number in parenthesis, that number can be used instead of the text value.
| Option name | Possible values | Default value | When is it used | Notes |
|---|---|---|---|---|
| server-name | Any string (no semicolon allowed) | Dedicated Server | Always | This is the server name shown in the in-game server list. |
| gamemode | survival, creative, adventure | survival | Always or only for new players | |
| force-gamemode | true, false | false | Always |
force-gamemode=false(or force-gamemode is not defined in the server.properties file)
prevents the server from sending to the client gamemode values other
than the gamemode value saved by the server during world creation
even if those values are set in server.properties file after world creation. force-gamemode=true forces the server to send to the client gamemode values other than the gamemode value saved by the server during world creation if those values are set in server.properties file after world creation. |
| difficulty | peaceful, easy, normal, hard | easy | Always | |
| allow-cheats | true, false | false | Always | If true then cheats like commands can be used. |
| max-players | Any integer | 10 | Always | The maximum numbers of players that should be able to play on the server. Higher values have performance impact. |
| server-port | Integer between 1024 and 65535 | 19132 | Always | Values below 1024 may be used, but are generally reserved for well known applications |
| server-portv6 | Integer between 1024 and 65535 | 19133 | Always | Values below 1024 may be used, but are generally reserved for well known applications.
This property is ignored when transport=nethernet; in that mode a single dual-stack socket is opened on server-port instead. |
| transport | raknet, nethernet | raknet | Always | Selects the network transport used to accept client connections. See the Transport section below for details on the differences between the two modes
and for the additional options that apply when transport=nethernet. |
| server-ip | IPv4 or IPv6 literal, or empty | (empty) | When transport=nethernet |
The local address the server should bind its listening socket to. Leave empty to bind to all interfaces (the default).
Ignored when transport=raknet. |
| server-udp-ports | See notes | (empty) | When transport=nethernet |
Configures the UDP ports used for client peer-to-peer transport when running on NetherNet. See the UDP port configuration section below.
Ignored when transport=raknet. |
| enable-lan-visibility | true, false | true | Always | Listen and respond to clients that are looking for servers on the LAN. When transport=raknet this will cause the server to bind to
the default ports (19132, 19133) even when 'server-port' and 'server-portv6' have non-default values. Consider
turning this off if LAN discovery is not desirable, or when running multiple servers on the same host may lead to port conflicts. |
| level-name | Any string | Bedrock level | Always | The name of level to be used/generated. Each level has its own folder in /worlds. |
| level-seed | Any string | World creation | The seed to be used for randomizing the world. If left empty a seed will be chosen at random. | |
| online-mode | true, false | true | Always | If true, all connected players must be authenticated with Xbox Live. Clients connecting to remote (non-LAN) servers will always require Xbox Live authentication regardless of this setting. If the server accepts connections from the Internet, then it is highly recommended to enable online-mode. |
| allow-list | true, false | true | Always | If true then all connected players must be listed in the separate allowlist.json file.
See the Allowlist section. |
| enable-packet-rate-limiter | true, false | false | Always | If true, the packet rate limiter will be enabled with the configuration provided by the packetlimitconfig.json file.
See the Packet Rate Limit Config section. |
| view-distance | Any integer greater than 5 | 32 | Always | The maximum allowed view distance. Higher values have performance impact. |
| player-idle-timeout | Any positive integer, including 0 | 30 | Always | After a player has idled for this many minutes they will be kicked. If set to 0 then players can idle indefinitely. |
| max-threads | Any integer | 8 | Always | Maximum number of threads the server will try to use. If set to 0 or removed then it will use as many as possible. |
| tick-distance | An integer in the range [4, 12] | 4 | Always | The world will be ticked this many chunks away from any player. Higher values have performance impact. |
| default-player-permission-level | visitor, member, operator | member | Always | Which permission level new players will have when they join for the first time. |
| texturepack-required | true, false | false | Always | If the world uses any specific texture packs then this setting will force the client to use it. |
| content-log-file-enabled | true, false | false | Always | Enables logging content errors to a file. |
| compression-threshold | An integer in the range [0-65535] | 1 | Always | Determines the smallest size of raw network payload to compress. Can be used to experiment with CPU-bandwidth tradeoffs. |
| compression-algorithm | zlib, snappy | zlib | Always | Determines the compression algorithm to use for networking. |
| server-authoritative-movement-strict | true, false | false | Always | If true, will be more strict toward the Player position and be less permissive in accepting the client info. This will impact Player around moving block if there is high latency. |
| server-authoritative-dismount-strict | true, false | false | Always | If true, will be more strict toward the Player dismount position. This means clients will receive a correction on their dismount position in higher latency situation. |
| server-authoritative-entity-interactions-strict | true, false | false | Always | If true, will be more strict toward the Entity interactions. This will impact Players interacting with each other in higher latency situations. |
| player-position-acceptance-threshold | Any positive float | 0.5 | Always | This is the tolerance of discrepancies between the Client and Server Player position. This helps in problematic scenarios. The higher the number, the more tolerant the server will be before asking for a correction. Passed value of 1.0, the chance of missing cheating increases. |
| player-movement-action-direction-threshold | Any positive float in the range of [-1.00, 1.00] | 0.85 | Always | The amount that the direction the player is attacking can differ from the direction the player is looking as cos(x) where x is the angle between the two vectors. A value of 1 means the two vectors must be parallel, 0 means anything in front of the player, and -1 means any vector. |
| server-authoritative-block-breaking | true, false | false | Not when client-auth | If true, the server will compute block mining operations in sync with the client so it can verify that the client should be able to break blocks when it thinks it can. This setting cannot be combined with client authoritative movement and will be disabled if that setting is enabled. |
| server-authoritative-block-breaking-pick-range-scalar | Any float above 1.0 | 1.5 | When server-authoritative-block-breaking is true | This increase the range of block breaking. This is squared and multiplied with the default range. |
| chat-restriction | None, Dropped, Disabled | None | Always | This represents the level of restriction applied to the chat for each player that joins the server. "None" is the default and represents regular free chat. "Dropped" means the chat messages are dropped and never sent to any client. Players receive a message to let them know the feature is disabled. "Disabled" means that unless the player is an operator, the chat UI does not even appear. No information is displayed to the player. |
| disable-player-interaction | true, false | false | Always | If true, the server will inform clients that they should ignore other players when interacting with the world. This is not server authoritative. | client-side-chunk-generation-enabled | true, false | true | Always | If true, the server will inform clients that they have the ability to generate visual level chunks outside of player interaction distances. |
| block-network-ids-are-hashes | true, false | true | Always | If true, the server will send hashed block network ID's instead of id's that start from 0 and go up. These id's are stable and won't change regardless of other block changes. |
| disable-persona | true, false | false | Internal Use Only | |
| disable-custom-skins | true, false | false | Always | If true, disable players customized skins that were customized outside of the Minecraft store assets or in game assets. This is used to disable possibly offensive custom skins players make. | server-build-radius-ratio | Disabled, 0.0-1.0 | Disabled | Always | If "Disabled" the server will dynamically calculate how much of the player's view it will generate, assigning the rest to the client to build. Otherwise from the overridden ratio tell the server how much of the player's view to generate, disregarding client hardware capability. Only valid if client-side-chunk-generation-enabled is enabled. |
The transport property selects which network protocol the server uses to accept client connections.
Two values are supported:
server-port (IPv4) and server-portv6 (IPv6), and clients connect to that address
and port. This is the mode used by all previous releases.
server-port for an HTTP-based signaling handshake, then negotiates a UDP connection with
each client that carries the gameplay traffic.
When transport=nethernet, the following additional properties apply:
server-ip — The local address to bind the listening socket to. Leave empty to
bind to all interfaces. Accepts either an IPv4 or IPv6 literal. When empty, the server prefers a
dual-stack IPv6 socket so that one listener serves both IPv4 and IPv6 clients, and falls back to
IPv4-only if dual-stack is unavailable.
server-udp-ports — Constrains the local UDP port range and optionally publishes
an external NAT/port-forwarding mapping for clients. See the
UDP port configuration for NetherNet section below.
Tip for servers open to the Internet: Because the NetherNet handshake on
server-port speaks HTTP/TCP, it is recommended to put a reverse proxy (for example
nginx, HAProxy, or a managed edge service) in front of server-port to terminate
connections, enforce request and rate limits, and absorb abusive traffic before it ever reaches the
server. Only the signaling traffic on server-port needs to be forwarded through the
proxy — the gameplay traffic flows directly between the client and the server over the
negotiated UDP connection.
By default, the NetherNet transport allocates UDP ports for client connections from the operating system's
ephemeral range, which is fine for most LAN and outbound-friendly deployments but is not always suitable for
servers that sit behind a firewall or NAT. server-udp-ports lets you pin the local port range
the server uses, and/or describe a port mapping that clients should connect to.
Each entry takes one of the following forms:
internal or start-end — restricts the UDP port allocation window to the
given port or inclusive range. Use this to confine the server to a specific set of local ports (for
example, a firewall-opened range).
[ip:]external[-external]:internal[-internal] — publishes a NAT or port-forwarding
mapping that the server advertises to clients. Use this when the address or port the server binds locally
differs from the address or port clients must connect to (for example, when the server sits behind a 1:1
NAT or a router-level port-forwarding rule).
internal is the local UDP port the server actually binds to.
external is the port clients reach from outside — the port the NAT or router
translates to internal. The optional ip: prefix is the public address
those clients see (IPv6 literals must be enclosed in square brackets); omit it to advertise the
host's own addresses.
start-end range. If both are ranges they must
be the same length, and each external port is paired with the internal port at the same offset.
Multiple entries can be supplied on a single line separated by commas, and the property may also appear on more than one line to accumulate entries. Some examples:
# Restrict local UDP allocation to the specified range server-udp-ports=49152-49200 # Bind locally to ports 32000-32100 and advertise them to clients as external ports 19132-19232 server-udp-ports=19132-19232:32000-32100 # Same, but advertised on a specific public IPv4 address server-udp-ports=203.0.113.10:19132-19232:32000-32100 # Same, but advertised on a specific public IPv6 address server-udp-ports=[2001:db8::1]:19132-19232:32000-32100
When unpacking you will see a few folders and the binary executable. When starting the server for the first time a bunch of new (empty) folders will be created. The folders you should care about are the following:
| Folder name | Purpose |
|---|---|
| behavior_packs | This is where new behavior packs can be installed. At the moment there's no way of activating them in a level. |
| resource_packs | This is where new resource packs can be installed. At the moment there's no way of activating them in a level. |
| worlds | This folder will be created at startup if it doesn't already exist. Every world created will have a folder named according to their level-name inside the server.properties file. |
| system_behavior_packs | This folder is not created automatically at server startup. It is used to store system administrator behavior packs that can be applied globally across all worlds. Additionally, the pack and it's module's uuid values are protected, and will result in other user packs failing to load if using the same ID. |
| system_resource_packs | This folder is not created automatically at server startup. It is used to store system administrator resource packs that can be applied globally across all worlds. Additionally, the pack and it's module's uuid values are protected, and will result in other user packs failing to load if using the same ID. |
If the allow-list property is enabled in server.properties then the server will only allow selected users to connect. To allow a user to connect you need to know their Xbox Live Gamertag. The easiest way to add a user to the allowlist is to use the command allowlist add <Gamertag> (eg: allowlist add ExampleName). Note: If there is a white-space in the Gamertag you need to enclose it with double quotes: allowlist add "Example Name"
If you later want to remove someone from the list you can use the command allowlist remove <Gamertag>.
The allowlist will be saved in a file called allowlist.json. If you want to automate the process of adding or removing players from it you can do so. After you've modified the file you need to run the command allowlist reload to make sure that the server knows about your new change.
NOTE: This file was previously named whitelist.json. For backwards compatability, if a whitelist.json file is also present, it will be used instead of allowlist.json.
To migrate, delete the default allowlist.json file, rename whitelist.json to allowlist.json, then restart the server.
The file contains a JSON array with objects that contains the following key/values.
| Key | Type | Value |
|---|---|---|
| name | String | The gamertag of the user. |
| xuid | String | Optional. The XUID of the user. If it's not set then it will be populated when someone with a matching name connects. |
| ignoresPlayerLimit | Boolean | True if this user should not count towards the maximum player limit. Currently there's another soft limit of 30 (or 1 higher than the specified number of max players) connected players, even if players use this option. The intention for this is to have some players be able to join even if the server is full. |
Example allowlist.json file:
[
{
"ignoresPlayerLimit": false,
"name": "MyPlayer"
},
{
"ignoresPlayerLimit": false,
"name": "AnotherPlayer",
"xuid": "274817248"
}
]
If the enable-packet-rate-limiter property is enabled in server.properties, the server will use the packet rate limiter feature. Following the configuration described by the packetlimitconfig.json file, specific types of packets will be limited and rejected.
To reload the packet rate limiter configuration on the flight, use the server command reloadpacketlimitconfig. The server will reload the configuration from the packetlimitconfig.json file and update it for all of its clients.
The packetlimitconfig.json file contains a JSON array with a list of limit groups. Each group contains a list of packet ids and the corresponding packet rate limit algorithm that will be applied to them. Only BucketPacketLimitAlgorithm is currently supported. Additionally, the file can also use a default algorithm that will be applied to limit the rate for all packet types, on top of the ones specified by the limit groups.
BucketPacketLimitAlgorithm requires two parameters:
| Key | Type | Value |
|---|---|---|
| drainRatePerSec | float | The drain rate of the bucket per second. Value must be in the range [0.0f, 10000.0f] |
| maxBucketSize | uint32_t | The maximum size of the bucket. Value must be in the range [1, 10000] |
Example of the packetlimitconfig.json file:
{
"limitGroups": [{
"minecraftPacketIds": [193, 4],
"algorithm": {
"name": "BucketPacketLimitAlgorithm",
"params": {
"drainRatePerSec": 0.0013,
"maxBucketSize": 1
}
}
}, {
"minecraftPacketIds": [9],
"algorithm": {
"name": "BucketPacketLimitAlgorithm",
"params": {
"drainRatePerSec": 10,
"maxBucketSize": 50
}
}
}],
"defaultAlgorithm": {
"name": "BucketPacketLimitAlgorithm",
"params": {
"drainRatePerSec": 0.0013,
"maxBucketSize": 1
}
}
}
You can adjust player specific permissions by assigning them roles in the permissions.json that is placed in the same directory as the server executable. The file contains a simple JSON object with XUIDs and permissions. Valid permissions are: operator, member, visitor. Every player that connects with these accounts will be treated according to the set premission. If you change this file while the server is running, then run the command permission reload to make sure that the server knows about your new change. You could also list the current permissions with permission list. Note that online-mode needs to be enabled for this feature to work since xuid requires online verification of the user account. If a new player that is not in this list connects, the default-player-permission-level option will apply.
Example permissions.json file:
[
{
"permission": "operator",
"xuid": "451298348"
},
{
"permission": "member",
"xuid": "52819329"
},
{
"permission": "visitor",
"xuid": "234114123"
}
]
If the server crashes it will automatically send us various information that helps us solve it for the future.
You can issue commands to the server by typing in the console. The following commands are available. < > means a parameter is required, [ ] means it's optional and | denotes different allowed values. Strings can be enclosed in double quotes, ", if they contain spaces.
| Command syntax | Description |
|---|---|
| kick <player name or xuid> <reason> | Immediately kicks a player. The reason will be shown on the kicked players screen. |
| stop | Shuts down the server gracefully. |
| save <hold | resume | query> | Used to make atomic backups while the server is running. See the backup section for more information. |
| allowlist <on | off | list | reload> |
See the allowlist section for more information. |
| allowlist <add | remove> <name> | Adds or removes a player from the allowlist file. The name parameter should be the Xbox Gamertag of the player you want to add or remove. You don't need to specify a XUID here, it will be resolved the first time the player connects. See the Allowlist section for more information. |
| permission <list | reload> |
See the Permissions section for more information. |
| op <player> |
Promote a player to |
| deop <player> |
Demote a player to |
| changesetting <setting> <value> | Changes a server setting without having to restart the server. Currently only two settings are supported to be changed, allow-cheats (true or false) and difficulty (0, peaceful, 1, easy, 2, normal, 3 or hard). They do not modify the value that's specified in server.properties. |
The server supports taking backups of the world files while the server is running. It's not particularly friendly for taking manual backups, but works better when automated. The backup (from the servers perspective) consists of three commands.
| Command | Description |
|---|---|
| save hold | This will ask the server to prepare for a backup. It’s asynchronous and will return immediately. |
| save query | After calling save hold you should call this command repeatedly to see if the preparation has finished. When it returns a success it will return a file list (with lengths for each file) of the files you need to copy. The server will not pause while this is happening, so some files can be modified while the backup is taking place. As long as you only copy the files in the given file list and truncate the copied files to the specified lengths, then the backup should be valid. |
| save resume | When you’re finished with copying the files you should call this to tell the server that it’s okay to remove old files again. |