RakNet

RakNet is a multiplayer networking library that manages connections and delivers messages over UDP. It adds features that UDP does not provide on its own, including retransmission of lost messages, delivery in order, and splitting large messages into smaller pieces.

Applications choose a delivery mode for each message. A message that must arrive can be sent reliably, while a time-sensitive update can use sequencing so that an older update does not replace a newer one. The original C++ library is available in the RakNet source archive.

Use in Bedrock Edition


In Bedrock Edition, RakNet handles the connection carrying Minecraft’s game data. Its job is to transport that data; the Bedrock game protocol defines what the data means, including login, world information, and player actions.

The two protocols have separate version numbers. The RakNet version is checked during the initial connection exchange, while the Bedrock protocol version determines which Minecraft packet formats the client and server understand.

NetherNet became the default transport for dedicated servers in 26.50. RakNet was marked as deprecated in Preview 26.60.22.

Protocol structure


RakNet traffic has two forms. Offline packets discover a server and negotiate a connection before normal message delivery begins. Connected packets travel inside frames, which carry the information needed to deliver their contents correctly.

LayerWhat it contains
UDP datagramOne message sent across the network.
RakNet frame setA datagram sequence number and one or more frames.
RakNet frameDelivery metadata and a payload, or one fragment of a larger payload.
Bedrock game-data payloadA batch of Minecraft packets, carried inside a RakNet frame.

A frame set can hold several frames. Their delivery modes are recorded separately, so receiving one datagram does not mean that every frame in it must be handled in the same way.

Data types


Packet fields are read in the order shown in their tables. Fixed-width numbers occupy a set number of bytes; strings and packet bodies have a length that determines how much data follows.

Big-endian stores the most significant byte first. Little-endian stores it last. RakNet uses both: frame indices are little-endian, while frame body lengths are big-endian.

TypeSizeEncoding or purpose
Byte1 byteUnsigned 8-bit integer, from 0 to 255.
Boolean1 byteUsually 0x00 for false and 0x01 for true.
Short2 bytesSigned 16-bit integer, from −32,768 to 32,767.
Unsigned short2 bytesUnsigned 16-bit integer, from 0 to 65,535.
Int / unsigned int4 bytesSigned or unsigned 32-bit value, as specified by the field.
Long8 bytes64-bit value; signedness depends on its purpose.
uint24le3 bytesUnsigned 24-bit little-endian value, used by datagram and frame indices.
StringVariableA 16-bit unsigned byte length, followed by that many string bytes.
Magic16 bytesFixed marker used by offline packets.
IPv4 address7 bytesVersion byte, four inverted address bytes, and a big-endian port.
IPv6 address29 bytesVersion byte, address family, port, flow information, IPv6 address, and scope ID.

Magic is a fixed marker used to recognize offline RakNet messages. It is always the following 16 bytes:

00 ff ff 00 fe fe fe fe fd fd fd fd 12 34 56 78

An IPv4 address starts with a version byte of 4, followed by four inverted address bytes and a big-endian port. IPv6 starts with 6 and uses the longer layout described above.[1]

Common fields

FieldMeaning
GUIDA 64-bit identifier used to distinguish RakNet peers. It is separate from a Minecraft account identifier.
TimestampA time value included in a request or response, often echoed to relate the reply to the original request.
MTUMaximum transmission unit: the packet size negotiated for the connection. It limits how much data fits in a datagram.
Ordering channelA separate stream for ordering messages. Order is maintained within a channel rather than across all traffic.

Handshake sequence


The connection is established in two stages. First, the peers agree on the transport version and MTU. They then exchange connected messages to accept and confirm the session. C → S means client to server; S → C means server to client.

Opening the connection

  1. C → S — Open Connection Request 1: the client announces its RakNet version and sends a padded MTU probe.
  2. S → C — Open Connection Reply 1: the server returns its GUID and selected MTU. An unsupported version receives Incompatible Protocol instead.
  3. C → S — Open Connection Request 2: the client supplies its GUID, the server address, and the negotiated MTU.
  4. S → C — Open Connection Reply 2: the server confirms the settings and reports the client address it sees.

Confirming the session

  1. C → S — Connection Request: the client requests acceptance over the connected transport.
  2. S → C — Connection Request Accepted: the server accepts and returns address and timing information.
  3. C → S — New Incoming Connection: the client confirms receipt of that acceptance.

After this exchange, Bedrock continues with its game-protocol login. Server discovery is separate: an Unconnected Ping and Pong can exchange server-list information without opening a session.

Packets


Packet identifiers are hexadecimal. Fields are listed in serialization order after the packet ID. Optional security fields and internal-address counts can vary by implementation.[2]

Unconnected Ping

Packet ID: 0x01 / 0x02.

Asks a server to identify itself before a session is opened. The server echoes the supplied timestamp in its Pong, allowing the response to be matched to the request. 0x01 requests a normal reply; 0x02 requests one only if the server accepts incoming connections.

FieldTypeDescription
TimeLongClient ping timestamp, echoed in the response.
MagicMagicOffline packet marker.
Client GUIDLongClient identifier.

Unconnected Pong

Packet ID: 0x1c.

Returns the server’s GUID and advertisement in response to an Unconnected Ping. Bedrock reads the advertisement to display server information before the player joins.

FieldTypeDescription
TimeLongOriginal ping timestamp.
Server GUIDLongServer identifier.
MagicMagicOffline packet marker.
Server ID stringStringServer advertisement and list information.

Bedrock server advertisement

The Server ID string is a semicolon-separated advertisement. Common fields include the edition marker, server name (MOTD), Bedrock protocol and game versions, current and maximum player counts, server GUID, game mode, and port information. Its exact layout depends on the game version. These values describe the advertised server; they are not the RakNet handshake’s protocol version.

Connected Ping

Packet ID: 0x00.

Sends a timestamp over an established session to measure connection latency. Either peer may send it; it is commonly delivered unreliably.

FieldTypeDescription
TimeLongSender’s ping timestamp.

Connected Pong

Packet ID: 0x03.

Answers a Connected Ping by returning the original ping timestamp and the responder’s own timestamp. The echoed value relates this response to a particular ping.

FieldTypeDescription
Ping timeLongTimestamp from the incoming ping.
Pong timeLongResponder’s timestamp.

Open Connection Request 1

Packet ID: 0x05.

Starts connection negotiation. The client identifies its RakNet version and pads the datagram with zero bytes to probe a usable packet size. The padding is not a numeric MTU field.

FieldTypeDescription
MagicMagicOffline marker.
Protocol versionByteRakNet transport version requested by the client.
PaddingZero bytesZero padding used to probe the path MTU.

Open Connection Reply 1

Packet ID: 0x06.

Answers the first request with the server GUID, security setting, and selected MTU. If the RakNet version is unsupported, the server sends Incompatible Protocol instead.

FieldTypeDescription
MagicMagicOffline marker.
Server GUIDLongServer identifier.
Use securityBooleanWhether RakNet security negotiation is used.
CookieInt, conditionalIncluded when the security variant supplies a cookie.
MTUUnsigned shortSelected MTU.

Open Connection Request 2

Packet ID: 0x07.

Returns the negotiated MTU together with the server address and client GUID. Security-enabled variants also return the cookie supplied by the server.

FieldTypeDescription
MagicMagicOffline marker.
CookieInt, conditionalReturned when supplied by the server.
Has security challengeBoolean, conditionalPresent when security is enabled.
Server addressAddressAddress used for the server connection.
MTUUnsigned shortNegotiated size.
Client GUIDLongClient identifier.

Open Connection Reply 2

Packet ID: 0x08.

Confirms the peer connection and MTU. Its client-address field is the endpoint observed by the server, rather than an address copied from the client.

FieldTypeDescription
MagicMagicOffline marker.
Server GUIDLongServer identifier.
Client addressAddressClient endpoint observed by the server.
MTUUnsigned shortConfirmed size.
Encryption enabledBooleanWhether RakNet encryption is enabled.

Connection Request

Packet ID: 0x09.

Requests acceptance after the offline negotiation. Unlike the two Open Connection requests, this message travels through RakNet’s connected framing layer.

FieldTypeDescription
GUIDLongClient identifier.
TimeLongRequest timestamp.
Use securityBooleanSecurity request indicator.

Connection Request Accepted

Packet ID: 0x10.

Accepts the client’s request and returns its assigned system index, address information, and timestamps. The request timestamp matches the preceding Connection Request.

FieldTypeDescription
Client addressAddressClient endpoint.
System indexUnsigned shortIndex assigned by the server.
Internal addressesAddress array10 entries in the documented layout.
Request timeLongTimestamp from Connection Request.
TimeLongServer acceptance timestamp.

New Incoming Connection

Packet ID: 0x13.

Completes the exchange by confirming that the client received Connection Request Accepted. It supplies address and timing information to the server.

FieldTypeDescription
Server addressAddressServer endpoint.
Internal addressesAddress array20 entries in the documented Bedrock layout.
Incoming timestampLongConnection timing value.
Server timestampLongServer timing value.

Disconnection Notification

Packet ID: 0x15.

Notifies the other peer that the sender is ending the session. The packet has no additional payload in this layout.

Incompatible Protocol

Packet ID: 0x19.

Rejects an unsupported RakNet transport version and reports the server’s version. This response concerns the RakNet handshake, not Bedrock’s separate game-protocol compatibility check.

FieldTypeDescription
ProtocolByteProtocol version advertised by the server.
MagicMagicOffline marker.
Server GUIDLongServer identifier.

Frame Set Packet

Packet ID: commonly 0x80–0x8d.

A frame set carries one or more frames between connected peers. It contains a datagram sequence number followed by the frames. A frame-set datagram is identified by:

(packet_id & 0x80) == 0x80 && (packet_id & 0x60) == 0

The second condition distinguishes frame sets from ACK and NACK packets.

Datagram fieldTypePurpose
Packet ID / flagsByteIdentifies the data-datagram form.
Sequence numberuint24leDatagram-level number used by ACK/NACK records.
FramesOne or more framesContinue parsing until the datagram payload is consumed.

Frame structure

Frame fieldTypePresent when / purpose
FlagsByteUpper three bits select reliability; 0x10 indicates a split frame.
Body lengthUnsigned short, big-endianLength in bits, not bytes.
Reliable indexuint24leReliable modes; detects duplicate reliable messages.
Sequenced indexuint24leSequenced modes; identifies older updates.
Ordered indexuint24leOrdered or sequenced modes that use an ordering channel.
Ordering channelByteAssociated ordering stream; up to 32 channels in the standard implementation.
Split countUnsigned intTotal number of fragments; present only in split frames.
Split IDUnsigned shortSplit frames only: identifies the message being reassembled.
Split indexUnsigned intSplit frames only: this fragment’s position.
Bodyceil(bit_length / 8) bytesEncapsulated payload or fragment.

Reliable indices are present in modes 2, 3, and 4. Sequenced indices are present in modes 1 and 4. Ordering indices and channels are present in modes 1, 3, and 4. Split fields are included only when the split flag is set.

Fragmentation

When a message does not fit in one frame, it is split into fragments. Each fragment carries a split ID, a total fragment count, and its position within the message. The receiver groups matching fragments and reassembles their payloads before delivering the complete message.

The body-length field still describes this frame’s payload in bits. A value of 80 therefore describes 10 bytes, while a split count of 3 means three fragments, not three bytes.

Reliability types

Reliability, sequencing, and ordering answer different questions. Reliability controls whether missing data is resent. Sequencing prevents an older update from replacing a newer one. Ordering makes messages reach the application in send order within their channel.[3]

IDModeReliableSequencedOrdered
0UnreliableNoNoNo
1Unreliable sequencedNoYesNo
2ReliableYesNoNo
3Reliable orderedYesNoYes
4Reliable sequencedYesYesNo
5Unreliable with ACK receiptNoNoNo
6Reliable with ACK receiptYesNoNo
7Reliable ordered with ACK receiptYesNoYes

Modes 5–7 add delivery receipts in the original library and are serialized as modes 0, 2, and 3, respectively.[4]

For example, if update B is newer than update A, sequenced delivery can discard A when it arrives after B. With reliable ordered delivery, B waits if an earlier message is missing. Reliable delivery without ordering can deliver B first and deliver A when it is recovered.

Game Packet

Packet ID: 0xfe.

Carries a batch of Bedrock game packets inside a RakNet frame. The batch’s compression, encryption, and individual packet formats are part of the Bedrock game protocol.

FieldTypeDescription
BodyBytesBatched Bedrock game-protocol data.

NACK

Packet ID: 0xa0.

Reports frame-set datagrams that have not arrived. The sender uses these missing sequence numbers to retransmit reliable data when required. An unreliable payload is not made reliable by being listed in a NACK.

FieldTypeDescription
Record countUnsigned shortNumber of records that follow.
Is singleBoolean, per recordTrue selects one sequence number; false selects a range.
Sequence numberuint24lePresent for a single record.
Range startuint24lePresent for a range; first datagram number.
Range enduint24lePresent for a range; last datagram number.

ACK

Packet ID: 0xc0.

Reports frame-set datagrams that were received. Acknowledgment refers to transport receipt; it does not mean that a Minecraft action has finished. The record format matches NACK and supports individual numbers or inclusive ranges.

FieldTypeDescription
Record countUnsigned shortNumber of records that follow.
Is singleBoolean, per recordTrue selects one sequence number; false selects a range.
Sequence numberuint24lePresent for a single record.
Range startuint24lePresent for a range; first datagram number.
Range enduint24lePresent for a range; last datagram number.

Libraries


The original C++ library and independent implementations are listed below. Some target Bedrock or older Pocket Edition versions, while others provide general RakNet networking. Their supported protocol versions and features differ. License labels are summaries; the repository’s license file specifies the applicable terms.

NameLanguageDescriptionLicense
go-raknetGoRakNet implementation used by Dragonfly.MIT
NetrexMC RakNetRustAsynchronous RakNet implementation.Apache-2.0
PieRakNetPythonRakNet implementation for PieMC.GPL-3.0
Cloudburst NetworkJavaNetworking components for CloudburstMC projects.Apache-2.0
rak-netPythonImplementation originally developed for Podrum.GPL-2.0
JRakNetJavaJava RakNet protocol implementation.MIT
netty-raknetJavaRakNet support for Netty.MIT
JRakLibPlusJavaServer library derived from RakLib and JRakLib.LGPL
RakLibPHPLightweight RakNet server implementation.GPL-3.0
raknetJavaScriptNode.js UDP networking library following RakNet.MIT
PyRakLibPythonPython port of RakLib.GPL
rust-raknetRustRust RakNet implementation.MIT
BalticaTypeScriptBedrock toolkit with a RakNet implementation.See repository.
RakNet.PyPythonProtocol version 5 implementation for older Pocket Edition versions.GPL
LavishMC RakNetC++Fork of the original implementation.BSD
RakNet — originalC++Archived original library.BSD-2-Clause

References


  1. ↑ "RakNet protocol notes — types and addresses" - GolemOrg
  2. ↑ "MessageIdentifiers.h — built-in packet IDs" - Oculus VR
  3. ↑ "PacketPriority.h — reliability modes" - Oculus VR
  4. ↑ "ReliabilityLayer.cpp — frame serialization" - Oculus VR