Bolt Protocol handshake specification
All Bolt connections begin with a handshake to negotiate which version of the messaging protocol to use. Following a successful negotiation, the agreed messaging protocol then takes ownership of the connection for the remainder of its lifetime. The handshake itself is not versioned.
Bolt is a client-server protocol designed primarily for executing queries against a database server. Communication occurs through request-response exchanges, in much the same way as HTTP. Unlike HTTP, however, Bolt connections are stateful.
Byte values are represented using hexadecimal notation unless otherwise specified. |
Endianness
Bolt requires that all values that can vary by endianness should be transmitted using network byte order, also known as big-endian byte order. This means that the most significant part of the value is written to the network or memory space first and the least significant part is written last.
Connection and disconnection
Bolt communication is intended to take place over a TCP connection.
The default port is TCP 7687
but any port can be used.
There is no formal shutdown procedure for a Bolt connection. Either peer may close the connection at TCP level at any time. Both client and server should be prepared for that to occur and should handle it appropriately.
Handshake
Immediately following a successful connection, the client MUST initiate a handshake. This handshake is a fixed exchange used to determine the version of messaging protocol that follows.
Bolt identification
The first part of the handshake is used to identify to the server that this is a Bolt connection. It should be sent by a client immediately following the establishment of a successful connection and does not require a server response.
The identification consists of the following four bytes:
C: 60 60 B0 17
Version negotiation
After identification, a small client-server exchange occurs to determine which version of the messaging protocol to use. In this, the client submits exactly four protocol versions, each encoded as a big-endian 32-bit unsigned integer for a total of 128 bits. Protocol version zero can be used as a placeholder if fewer than four versions are required in the exchange. Should a match be found for a version supported by the server, the response will contain that version encoded as a single 32-bit integer. If no match is found, a zero value is returned followed by immediate closure of the connection by the server.
Within this exchange, a zero value (four zero bytes) always represents “no protocol version”. For the client, this can be used as a filler if fewer than four protocol versions are known. For the server, this indicates no version match has been found.
A server should assume that the versions contained within a client’s request have been sent in order of preference. Therefore, if a match occurs for more than one version, the first match should be selected.
C: 60 60 B0 17 C: 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 S: 00 00 00 01
C: 60 60 B0 17 C: 00 00 00 02 00 00 00 01 00 00 00 00 00 00 00 00 S: 00 00 00 02
C: 60 60 B0 17 C: 00 00 00 03 00 00 00 02 00 00 00 01 00 00 00 00 S: 00 00 00 02
C: 60 60 B0 17 C: 00 00 00 03 00 00 00 00 00 00 00 00 00 00 00 00 S: 00 00 00 00
Bolt version 4.3
With Bolt version 4.3, the version scheme supports ranges of minor versions. The first 8 bits are reserved. The next 8 bits represent the number of consecutive minor versions below the specified minor (next 8 bits) and major (next 8 bits) version that are supported.
The range cannot span multiple major versions. |
00 02 03 04
C: 60 60 B0 17 C: 00 03 03 04 00 00 01 04 00 00 00 04 00 00 00 03 S: 00 00 01 04
The client has to specify all versions prior to 4.3 explicitly since servers that only support those protocol versions might not support ranges. The example makes use of the fact that Bolt 4.1 and 4.2 are equivalent and only offer 4.3, 4.2, 4.0, and 3, but specify a range (4.3-4.0), in case the server supports ranges. |
Bolt version 4.0
With Bolt version 4.0 the version scheme supports major and minor versioning number. The first 16 bits are reserved. 8 bits represents the minor version. 8 bits represents the major version.
00 00 01 04
C: 60 60 B0 17 C: 00 00 01 04 00 00 00 04 00 00 00 03 00 00 00 00 S: 00 00 01 04