Bolt Protocol message specification

The message specification describes the message exchanges that take place on a connection following a successful Bolt handshake. For details of establishing a connection and performing a handshake, see Bolt Protocol handshake specification.

The Bolt protocol communicates with specific versioned messages.

Bolt Protocol server state specification

For the server, each connection using the Bolt Protocol will occupy one of several states throughout its lifetime. This state is used to determine what actions may be undertaken by the client.

For more information, see the corresponding version of the Bolt Protocol server state specification.

Server signals

Jump ahead means that the signal is immediately available before any messages are processed in the message queue.

Server signal Jump ahead Description

<INTERRUPT>

X

an interrupt signal

<DISCONNECT>

a disconnect signal

Protocol errors

If a server or client receives a message type that is unexpected, according to the transitions described in this document, it must treat that as a protocol error. Protocol errors are fatal and should immediately transition the server state to DEFUNCT, closing any open connections.

Session

Each connection to the server creates a new session that lives until that connection is closed. Each session is isolated and the server keeps track of the current state, based on the requests and responses exchanged within that session. A session ends when the socket for that connection is closed. Typically, this will be closed by the client.

Message exchange

Messages are exchanged in a request-response pattern between client and server. Each request consists of exactly one message and each response consists of zero or more detail messages followed by exactly one summary message. The presence or absence of detail messages in a response is directly related to the type of request message that has been sent. In other words, some request message types elicit a response that may contain detail messages, others do not.

Messages may also be pipelined. In other words, clients may send multiple requests eagerly without first waiting for responses. When a failure occurs in this scenario, servers must ignore all subsequent requests until the client has explicitly acknowledged receipt of the failure. This prevents inadvertent execution of queries that may not be valid. More details of this process can be found in the sections below.

Serialization

Messages and their contents are serialized into network streams using PackStream Specification Version 1. Each message is represented as a PackStream structure that contains a fixed number of fields. The message type is denoted by the PackStream structure tag byte and each message is defined in the Bolt protocol. Serialization is specified with PackStream Version 1.

Chunking

A layer of chunking is also applied to message transmissions as a way to more predictably manage packets of data. The chunking process allows the message to be broken into one or more pieces, each of an arbitrary size, and for those pieces to be transmitted within separate chunks. Each chunk consists of a two-byte header, detailing the chunk size in bytes followed by the chunk data itself. Chunk headers are 16-bit unsigned integers, meaning that the maximum theoretical chunk size permitted is 65,535 bytes.

Each encoded message must be terminated with a chunk of zero size, i.e.

00 00

This is used to signal message boundaries to a receiving parties, allowing blocks of data to be fully received without requiring that the message is parsed immediately. This also allows for unknown message types to be received and handled without breaking the messaging chain.

The Bolt protocol encodes each message using a chunked transfer encoding.

  • Each message is transferred as one or more chunks of data.

  • Each chunk starts with a two-byte header, an unsigned big-endian 16-bit integer, representing the size of the chunk not including the header.

  • A message can be divided across multiple chunks, allowing client and server alike to transfer large messages without having to determine the length of the entire message in advance.

  • Chunking applies on each message individually.

  • One chunk cannot contain more than one message.

  • Each message ends with two bytes with the value 00 00, these are not counted towards the chunk size (you may consider them as individual chunks of size 0).

  • With version 4.1+, the NOOP chunk (empty chunk) is used to send an empty chunk and the purpose is to be able to support a keep alive behaviour on the connection.

Examples of how Bolt chunks messages

Example of a message in one chunk

Message data containing 16 bytes:

00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

results in the following chunk:

00 10 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 00 00

with the chunk header 00 10 and the end marker 00 00.

Example of a message split in two chunks

Message data containing 20 bytes:

00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 01 02 03 04

results in chunk 1 and chunk 2:

00 10 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
00 04 01 02 03 04 00 00

with the chunk 1 header 00 01 and no end marker for chunk 1, still message data. Chunk 2 has a header 00 04 and an end marker 00 00.

Example with two messages

Message 1 data containing 16 bytes:

00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

Message 2 data containing 8 bytes:

0F 0E 0D 0C 0B 0A 09 08

are both encoded with chunking:

00 10 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 00 00
00 08 0F 0E 0D 0C 0B 0A 09 08 00 00
Example with two messages with a NOOP in between

Message 1 data containing 16 bytes:

00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

Message 2 data containing 8 bytes:

0F 0E 0D 0C 0B 0A 09 08

The two messages encoded with chunking and a NOOP(empty chunk) in between:

00 10 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 00 00
00 00
00 08 0F 0E 0D 0C 0B 0A 09 08 00 00

Pipelining

The client may send multiple requests eagerly without first waiting for responses.

Transaction

A transaction is the concept of atomic units of work.

The concept of Transaction is when the server is in the READY state and the transaction is opened with the request message RUN and the response of a summary message SUCCESS. The Transaction is successfully closed with the summary message SUCCESS for the request message PULL_ALL or the request message DISCARD_ALL.

Version 3 of the Bolt Protocol introduces the concept of Auto-commit Transaction and Explicit Transaction. Auto-commit Transaction is the server in the READY state and the transition to the STREAMING state. The transaction is opened with the request message RUN and the response of a summary message SUCCESS.

The Auto-commit Transaction is successfully closed with the summary message SUCCESS for the request message PULL_ALL or the request message DISCARD_ALL. Thus, the Auto-commit Transaction can only contain one RUN request message.

In version 4 of the Bolt Protocol, the DISCARD_ALL and PULL_ALL messages are renamed to DISCARD and PULL and new fields are introduced.

Example with Bolt v4
...
C: HELLO ...
S: SUCCESS ...  // Server is in READY state

C: RUN ...      // Open a new Auto-commit Transaction
S: SUCCESS ...  // Server is in STREAMING state

C: PULL ...
S: RECORD ...
   ...
S: RECORD ...
S: SUCCESS {"has_more": true, ...}  // Server is still in STREAMING state

C: PULL
S: RECORD ...
   ...
S: RECORD ...
S: SUCCESS {"has_more": false, ...}  // Server is in READY state and this implies that the Auto-commit Transaction is closed.

In version 1, HELLO is called INIT and Auto-commit Transaction is just Transaction. The field has_more=true/false is introduced in version 4. See also the corresponding version of the Bolt Protocol server state specification.

The Explicit Transaction is introduced in version 3 of Bolt and is a more generic transaction that can contain several RUN request messages. The concept of Explicit Transaction is when the server is in the READY state and the transaction is opened with the request message BEGIN and the response of a summary message SUCCESS (thus transition into the TX_READY server state).

The Explicit Transaction is successfully closed with the request message COMMIT and the response of a summary message SUCCESS. The result stream (detail messages) must be fully consumed or discarded by a client before the server can transition to the TX_READY state and thus be able to close the transaction with a COMMIT request message. It can be gracefully discarded and set to the initial server state of READY with the request message ROLLBACK.

Example with Bolt v4
...
C: HELLO ...
S: SUCCESS ...  // Server is in READY state

C: BEGIN ...    // Open a new Explicit Transaction
S: SUCCESS ...  // Server is in TX_READY state

C: RUN ...
S: SUCCESS {"qid": 123, ...} // Server is in TX_STREAMING state, one stream is open

C: RUN ...
S: SUCCESS {"qid": 456, ...} // Server is in TX_STREAMING state, two streams are open

C: PULL {"qid": 123, ...}
S: RECORD ...
   ...
S: RECORD ...
S: SUCCESS {"has_more": true, ...}  // Server is still in TX_STREAMING state, two streams are still open

C: PULL {"qid": 123, ...}
S: RECORD ...
   ...
S: RECORD ...
S: SUCCESS ... has_more=false  // Server is still in TX_STREAMING state, one stream is still open

C: PULL {"qid": 456, ...}
S: RECORD ...
   ...
S: RECORD ...
S: SUCCESS {"has_more": false, ...}  // Server is in TX_READY state, all streams have been fully consumed

C: COMMIT   // Close the Explicit Transaction
S: SUCCESS  // Server is in READY state

In version 3, PULL is called PULL_ALL. Additionally, there are no fields, e.g qid=123 and has_more=true/false available in version 3 of the Bolt Protocol.

More examples of message exchanges can be found in Appendix — Message exchange examples.

Messages

There are three different kinds of messages:

  • Request message - the client sends a message.

  • Summary message - the server always responds with one summary message if the connection is still open.

  • Detail message - the server always responds with zero or more detail messages before sending a summary message.

Message Signature Type of message Fields Description

HELLO

01

Request

extra::Dictionary(user_agent::String, routing::Dictionary(address::String), notifications_minimum_severity::String, notifications_disabled_categories::List<String>, bolt_agent::Dictionary(product::String, platform::String, language::String, language_details::String))

initialize connection (replaces INIT of v1 & v2)(routing::Dictionary(address::String) added in v4.1) (notifications_minimum_severity::String, notifications_disabled_categories::List<String> added in v5.2)(bolt_agent::Dictionary added in v5.3)

LOGON

6A

Request

scheme::String, …​

authenticates the user you send with the message

LOGOFF

6B

Request

logs off current user, becomes ready for another LOGON message

GOODBYE

02

Request

close the connection, triggers a <DISCONNECT> signal

ACK_FAILURE (only v1 and v2)

0E

Request

acknowledge a failure response (deprecated, use RESET instead with v3+)

RESET

0F

Request

reset the connection, triggers an <INTERRUPT> signal

RUN

10

Request

query::String, parameters::Dictionary, extra::Dictionary(bookmarks::List<String>, tx_timeout::Integer, tx_metadata::Dictionary, mode::String, db:String, notifications_minimum_severity::String, notifications_disabled_categories::List<String>)

execute a query (extra::Dictionary added in v3)(db:String added in v4.0) (notifications_minimum_severity::String, notifications_disabled_categories::List<String> added in v5.2)

DISCARD

2F

Request

extra::Dictionary(n::Integer, qid::Integer)

discard records (replaces DISCARD_ALL of v1, v2 & v3)(fields added in v4.0)

PULL

3F

Request

extra::Dictionary(n::Integer, qid::Integer)

fetch records (replaces PULL_ALL of v1, v2 & v3)(fields added in v4.0)

BEGIN

11

Request

extra::Dictionary(bookmarks::List<String>, tx_timeout::Integer, tx_metadata::Dictionary, mode::String, db::String, imp_user::String, notifications_minimum_severity::String, notifications_disabled_categories::List<String>)

begin a new transaction (added in v3)(db::String, imp_user::String added in v4.0) (notifications_minimum_severity::String, notifications_disabled_categories::List<String> added in v5.2)

COMMIT

12

Request

commit a transaction (added in v3)

ROLLBACK

13

Request

rollback a transaction (added in v3)

ROUTE

66

Request

routing::Dictionary(address::String), bookmarks::List<String>, extra::Dictionary(db::String, imp_user::String)

fetch the current routing table

SUCCESS

70

Summary

metadata::Dictionary

request succeeded

IGNORED

7E

Summary

request was ignored

FAILURE

7F

Summary

metadata::Dictionary(code::String, message::String)

request failed

RECORD

71

Detail

data::List

data values

Request message - HELLO

Introduced in bolt 3

The HELLO message request the connection to be authorized for use with the remote database and replaces the INIT request message of version 1 and 2. See below for more information on INIT.

The server must be in the CONNECTED state to be able to process a HELLO message. For any other states, receipt of an HELLO request must be considered a protocol violation and lead to connection closure.

Clients should send HELLO message to the server immediately after connection and process the corresponding response before using that connection in any other way.

Clients wishing to retry initialization should establish a new connection.

In version 4.1, routing::Dictionary(address::String) was added to indicate an indicator if the server should carry out routing, according to the given routing context.

In version 5.2, notifications_minimum_severity::String and notifications_disabled_categories::List<String> were added to be able to control the notification config. Disabling categories or severities allows the server to skip analysis for those, which can speed up query execution.

In version 5.3, bolt_agent::Dictionary was added to indicate the underlying driver and its version as opposed to the application using the driver in `user_agent.

On versions earlier than 5.1, the authentication token described on the LOGON message should be sent as part of the HELLO message instead.

routing values Description

{"routing": null} or {}

the server should not carry out routing

{"routing": {}}

the server should carry out routing

{"routing": {"address": "x.example.com:9001", "region": "example", …​}}

the server should carry out routing according to the given routing context

Signature: 01

Fields:
extra::Dictionary(
  auth::Dictionary(
    scheme::String,
    ...
  )
  user_agent::String,
  patch_bolt::List<String>,
  routing::Dictionary(address::String),
  notifications_minimum_severity::String,
  notifications_disabled_categories::List<String>,
  bolt_agent::Dictionary(
    product::String,
    platform::String,
    language::String,
    language_details::String
  )
)
  • auth contains the authentication information. See LOGON message for more information. Removed after bolt 5.0

  • The user_agent should conform to "Name/Version" for example "Example/4.1.0" (see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent for more information). Drivers should allow application code to set this value as it is meant to identify the application using the driver.

  • patch_bolt lets the driver request a patch to the protocol from the server. The patch must not be applied until the server acknowledges it in the SUCCESS response. Default: []. Introduced in bolt 4.3 Removed after bolt 4.4

    • "utc" is currently the only supported patch. If successfully negotiated, server and driver will use DateTime and DateTimeZoneId as defined in Bolt version 5.0.

  • The routing field should contain routing context information and the address field that should contain the address that the client initially tries to connect with e.g. "x.example.com:9001". Key-value entries in the routing context should correspond exactly to those in the original URI query string. Setting routing to null indicates that the server should not carry out any routing. Default: null. Introduced in bolt 4.1

  • The notifications_minimum_severity specifies the minimum severity a notification needs to have to be returned. Please see the Cypher documentation for acceptable entries, with the special value "OFF" added to the protocol, which disables all notifications. Sending null will make the server use its configured default. Default: null. Introduced in bolt 5.2

  • The notifications_disabled_categories is a list of notification categories that will not be returned. Please see the Cypher documentation for available categories. Sending null will make the server use its configured default. Default: null. Introduced in bolt 5.2

  • bolt_agent::Dictionary, as opposed to user_agent, is meant to identify the driver rather than the application using it. Drivers should not allow applications to change this value. When populating the fields, drivers should be careful not to include anything that could be used to identify a single machine or user. This field is mandatory. Introduced in bolt 5.3

    • product::String should conform to "Name/Version" and identify the driver for example "neo4j-fortran-alice-doe/42.69.0". This field is mandatory.

    • platform::String should describe the platform the driver is running on for example "Linux 5.15.0-58-generic; x86_64". Send null (or omit) if no platform information is available. Default: null.

    • language::String should conform to "Name/Version" and describe the language the driver/application is written in for example "Fortran/77". Send null (or omit) if no language information is available. Default: null.

    • language_details::String can contain further information about the language the driver/application is written in for example compiler, runtime, or interpreter and respective versions. Send null (or omit) if no language details are available. Default: null.

Detail messages:

No detail messages should be returned.

Valid summary messages:

  • SUCCESS

  • FAILURE

Examples

Synopsis
HELLO {extra}
Example 1
HELLO {"user_agent": "Example/4.1.0", "routing": {"address": "x.example.com:9001"}, "bolt_agent": {"product": "neo4j-fortran-alice-doe/42.69.0", "platform": "Linux 5.15.0-58-generic; x86_64", "language": "Fortran/77", "language_details": "gfortran 9.3.0"}}
Example 2
HELLO {"user_agent": "Example/4.2.0", "patch_bolt": ["utc"], "routing": {"address": "x.example.com:9001", "policy": "example_policy_routing_context", "region": "example_region_routing_context"}, "notifications_minimum_severity": "WARNING", "notifications_disabled_categories": ["HINT", "GENERIC"]}

Server response SUCCESS

A SUCCESS message response indicates that the client is permitted to exchange further messages. Servers can include metadata that describes details of the server environment and/or the connection.

The following fields are defined for inclusion in the SUCCESS metadata:

  • server::String (server agent string, example "Neo4j/4.1.0")

  • connection_id::String (unique identifier of the bolt connection used on the server side, example: "bolt-61")

  • patch_bolt::List<String> only if the client requested patches in the patch_bolt field of the request. The server will include the subset of requested patches (with the exact same string the client requests) if it supports it. From that point onward, the server-client communication must only use the patched protocol. Introduced in bolt 4.3 Removed after bolt 4.4

  • hints::Dictionary (set of optional configuration hints to be considered by the driver) Introduced in bolt 4.3

The hints dictionary may contain a set of optional configuration hints which may be interpreted or ignored by drivers at their own discretion in order to augment operations where applicable. A full listing of the available hints may be found in Appendix — Connection hints. Hints remain valid throughout the lifetime of a given connection and cannot be changed. As such, newly established connections may observe different hints and/or hint values as the server configuration is adjusted.

Example
SUCCESS {"server": "Neo4j/4.0.0", "hints": {"connection.recv_timeout_seconds": 120}}
Example 2
SUCCESS {"server": "Neo4j/4.4.0", "patch_bolt": ["utc"], "hints": {"connection.recv_timeout_seconds": 120}}

Server response FAILURE

A FAILURE message response indicates that the client is not permitted to exchange further messages. Servers may choose to include metadata describing the nature of the failure but must immediately close the connection after the failure has been sent.

Example
FAILURE {"code": "Example.Failure.Code", "message": "example failure"}

Request message INIT

Introduced in bolt 1 Removed after bolt 2

The INIT message is a request for the connection to be authorized for use with the remote database.

The request message INIT is only valid in version 1 and 2 and is replaced by the request message HELLO in version 3+.

The INIT message uses the structure signature 01 and passes two fields: user agent (String) and auth_token (Dictionary).

The server must be in the CONNECTED state to be able to process an INIT request. For any other states, receipt of an INIT request must be considered a protocol violation and lead to connection closure.

Clients should send INIT requests to the network immediately after connection and process the corresponding response before using that connection in any other way.

A receiving server may choose to register or otherwise log the user agent but may also ignore it if preferred.

The auth token should be used by the server to determine whether the client is permitted to exchange further messages. If this authentication fails, the server must respond with a FAILURE message and immediately close the connection. Clients wishing to retry initialization should establish a new connection.

Signature: 01

Fields:
user_agent::String,
auth_token::Dictionary(
  scheme::String,
  principal::String,
  credentials::String,
)
  • The user_agent should conform to "Name/Version" for example "Example/1.1.0" (see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent for more information).

  • The scheme is the authentication scheme. Predefined schemes are "none" and "basic". If no scheme is provided, it defaults to "none".

  • The auth_token must contain either just the entry {"scheme" : "none"} or the keys scheme, principal and credentials.

Detail messages:

No detail messages should be returned.

Valid Summary Messages:

  • SUCCESS

  • FAILURE

Examples

Synopsis
INIT "user_agent" {auth_token}
Example 1
INIT "Example/1.0.0" {"scheme": "none"}
Example 2
INIT "Example/1.0.0" {"scheme": "basic", "principal": "neo4j", "credentials": "password"}

Server response `SUCCESS`

A SUCCESS message response indicates that the client is permitted to exchange further messages. Servers can include metadata that describes details of the server environment and/or the connection.

The following fields are defined for inclusion in the SUCCESS metadata.

  • server::String (server agent string, example "Neo4j/3.4.0")

Example
SUCCESS {"server": "Neo4j/3.4.0"}

Server response `FAILURE`

A FAILURE message response indicates that the client is not permitted to exchange further messages.

Servers may choose to include metadata describing the nature of the failure but must immediately close the connection after the failure has been sent.

Example
FAILURE {"code": "Example.Failure.Code", "message": "example failure"}

Request message LOGON

Introduced in bolt 5.1

A LOGON message carries an authentication request.

This message is new in version 5.1. In previous versions, authentication was part of the HELLO message.

Signature: 6A

Fields:
auth::Dictionary(
  scheme::String,
  ...
)
  • The scheme is the authentication scheme. Predefined schemes are none, basic, bearer and kerberos (depending on the server’s capabilities).

  • Further entries in the message are passed to the implementation of the chosen authentication scheme. Their names, types, and defaults depend on that choice.

    • The scheme basic requires a username principal::String and a password credentials::String.

    • The scheme bearer merely requires a token credentials::String.

If authentication fails, the server responds with a FAILURE message and immediately closes the connection.

Examples

Synopsis
LOGON {auth}
Example 1
LOGON {"scheme": "basic", "principal": "user", "credentials": "password"}

Request message LOGOFF

Introduced in bolt 5.1

A LOGOFF message logs off the currently authenticated user. The connection is then ready for another LOGON message.

This message is new in version 5.1. No equivalent exists in previous versions.

Signature: 6B

Fields: No fields

Detail messages:

No detail messages should be returned.

Valid summary messages:

  • SUCCESS

  • FAILURE

Examples

Synopsis
LOGOFF
Example
LOGOFF

Server response SUCCESS

If a LOGOFF message request has been successfully received, the server should respond with a SUCCESS message and enter the AUTHENTICATION state.

Example
SUCCESS {}

Server response FAILURE

If LOGOFF message is received while the server is not in the READY state, it should trigger a FAILURE followed by immediate closure of the connection. The server may attach metadata to the message to provide more detail on the nature of the failure. Clients receiving a FAILURE in response to LOGOFF should treat that connection as DEFUNCT and dispose of it.

Example
FAILURE {"code": "Neo.ClientError.Request.Invalid", "message": "Message 'LogoffMessage{}' cannot be handled by a session in the FAILED state."}

Request message TELEMETRY

Introduced in bolt 5.4

The TELEMETRY message contains an integer representing which driver API was used.

The telemetry information is stored on the server’s metrics system. The client receives a SUCCESS response, unless it sends an invalid value for the api field, which results in a FAILURE response.

Clients should offer the user the option to disable sending telemetry. Further, the server might opt out of receiving telemetry from the client by sending the corresponding configuration hint in the SUCCESS message of the HELLO message. See Appendix — Connection hints for more information. If the client ignores the hint, the server must still accept the TELEMETRY message.

The message may only be sent in the READY state.

Signature: 54

Fields:
api::Integer

Valid values for api and the corresponding API associations are:

  • 0 — Managed transaction

  • 1 — Explicit transaction

  • 2 — Implicit transaction

  • 3 — Driver-level execute_query()

Detail messages:

No detail messages should be returned.

Valid summary messages:

  • SUCCESS

  • FAILURE

Examples

Synopsis
TELEMETRY api
Example 1
TELEMETRY 0

Server response SUCCESS

If a TELEMETRY message request is successfully received, the server responds with a SUCCESS and remains in its current state.

Example
SUCCESS {}

Server response FAILURE

If a TELEMETRY message contains a value that is not a valid api value or is sent in the wrong state, the server responds with a FAILURE message and enters the FAILED state.

Example 1
C: TELEMETRY 2
S: FAILURE {"code": "Neo.ClientError.Request.Invalid", "message": "Message of type TelemetryMessage cannot be handled by a session in the NEGOTIATION state."}
Example 2
C: TELEMETRY "oh no!"
S: FAILURE {"code": "Neo.ClientError.Request.Invalid", "message": "Illegal value: Expected IntValue but got StringValue."}
Example 3
C: TELEMETRY 9001
S: FAILURE {"code": "Neo.ClientError.Request.Invalid", "message": "Unknown driver interface type 9001."}

Request message GOODBYE

Introduced in bolt 3

The GOODBYE message notifies the server that the connection is terminating gracefully. On receipt of this message, the server should immediately shut down the socket on its side without sending a response.

A client may shut down the socket at any time after sending the GOODBYE message. This message interrupts the server current work if there is any.

Signature: 02

Fields: No fields.

Detail messages:

No detail messages should be returned.

Valid summary messages:

No summary messages should be returned.

Examples

Synopsis
GOODBYE
Example
GOODBYE

Request message ACK_FAILURE

Introduced in bolt 1 Removed after bolt 2

The request message ACK_FAILURE signals to the server that the client has acknowledged a previous failure and should return to a READY state.

The request message ACK_FAILURE is only valid in version 1 and 2 and the request message RESET should be used in its place in version 3+.

Signature: 0E

Fields: No fields.

Detail messages:

No detail messages should be returned.

Valid summary messages:

  • SUCCESS

  • FAILURE

The server must be in a FAILED state to be able to successfully process an ACK_FAILURE request. For any other states, receipt of an ACK_FAILURE request will be considered a protocol violation and will lead to connection closure.

Examples

Synopsis
ACK_FAILURE
Example
ACK_FAILURE

Server response `SUCCESS`

If an ACK_FAILURE request has been successfully received, the server should respond with a SUCCESS message and enter the READY state.

The server may attach metadata to the SUCCESS message.

Example
SUCCESS {}

Server response message `FAILURE`

If an ACK_FAILURE request is received while not in the FAILED state, the server should respond with a FAILURE message and immediately close the connection.

The server may attach metadata to the message to provide more detail on the nature of the failure.

Example
FAILURE {"code": "Example.Failure.Code", "message": "example failure"}

Request message RESET

Introduced in bolt 1

The RESET message requests that the connection should be set back to its initial RESET state, as if a HELLO (INIT in v1 and v2) (and a LOGON in v5.1+) had just successfully completed. The RESET message is unique in that, on arrival at the server, it jumps ahead in the message queue, stopping any unit of work that happens to be executing. All the queued messages originally in front of the RESET message will then be IGNORED until the RESET position is reached. Then from this point, the server state is reset to a state that is ready for a new session.

In version 1 and 2, the RESET message splits into two separate signals. First, an <INTERRUPT> signal jumps ahead in the message queue, stopping any unit of work that happens to be executing, and putting the state machine into an INTERRUPTED state. Second, the RESET queues along with all other incoming messages and is used to put the state machine back to READY when its turn for processing arrives. This essentially means that the INTERRUPTED state exists only transitionally between the arrival of a RESET in the message queue and the later processing of that RESET in its proper position. The INTERRUPTED state is therefore the only state to automatically resolve without any further input from the client and whose entry does not generate a response message.

Signature: 0F

Fields: No fields

Detail messages:

No detail messages should be returned.

Valid summary messages:

  • SUCCESS

  • FAILURE

Examples

Synopsis
RESET
Example
RESET

Server response SUCCESS

If a RESET message request has been successfully received, the server should respond with a SUCCESS message and enter the READY state.

Example
SUCCESS {}

Server response FAILURE

If RESET message is received before the server enters a READY state, it should trigger a FAILURE followed by immediate closure of the connection. The server may attach metadata to the message to provide more detail on the nature of the failure. Clients receiving a FAILURE in response to RESET should treat that connection as DEFUNCT and dispose of it.

Example
FAILURE {"code": "Example.Failure.Code", "message": "example failure"}

Request message RUN

Introduced in bolt 1

The RUN message requests that a Cypher query is executed with a set of parameters and additional extra data.

In version 3+, this message can both be used in an Explicit Transaction or an Auto-commit Transaction. The transaction type is implied by the message sequence:

  • Explicit Transaction: RUN while inside a transaction context started with BEGIN first.

  • Auto-commit Transaction: RUN without having started an explicit transaction with BEGIN first.

In version 5.2, notifications_minimum_severity::String and notifications_disabled_categories::List<String> were added to be able to control the notification config. Disabling categories or severities allows the server to skip analysis for those, which can speed up query execution.

Signature: 10

Fields:
query::String,
parameters::Dictionary,
extra::Dictionary(
  bookmarks::List<String>,
  tx_timeout::Integer,
  tx_metadata::Dictionary,
  mode::String,
  db::String,
  imp_user::String,
  notifications_minimum_severity::String,
  notifications_disabled_categories::List<String>
)
  • The query can be any Cypher query (including a procedure call).

  • The parameters is a dictionary of parameters to be used in the query string.

An Explicit Transaction (BEGIN+RUN) does not carry any data in the extra field.

For Auto-commit Transaction (RUN) the extra field carries:

  • extra contains additional options. Introduced in bolt 3

    • The bookmarks is a list of strings containing some kind of bookmark identification, e.g., ["neo4j-bookmark-transaction:1", "neo4j-bookmark-transaction:2"]. Default: [].

    • The tx_timeout is an integer in that specifies a transaction timeout in ms. Default: server-side configured timeout.

    • The tx_metadata is a dictionary that can contain some metadata information, mainly used for logging. Default: null.

    • The mode specifies what kind of server the RUN message is targeting. For write access use "w" and for read access use "r". Default: "w".

    • The db specifies the database name for multi-database to select where the transaction takes place. null and "" denote the server-side configured default database. Default: null. Introduced in bolt 4.0

    • The imp_user key specifies the impersonated user which executes this transaction. null denotes no impersonation (execution takes place as the current user). Default: null. Introduced in bolt 4.4

    • The notifications_minimum_severity specifies the minimum severity a notification needs to have to be returned. Please see the Cypher documentation for acceptable entries, with the special value "OFF" added to the protocol, which disables all notifications. Sending null will make the server use whatever was specified in the HELLO message of the current connection. Default: null. Introduced in bolt 5.2

    • The notifications_disabled_categories is a list of notification categories that will not be returned. Please see the Cypher documentation for available categories. Sending null will make the server use whatever was specified in the HELLO message of the current connection. Default: null. Introduced in bolt 5.2

Detail messages:

No detail messages should be returned.

Valid summary messages:

  • SUCCESS

  • IGNORED

  • FAILURE

The server must be in a READY or READY_TX (v3+) state to be able to successfully process a RUN request. If the server is in a FAILED or INTERRUPTED state, the request will be IGNORED. For any other states, receipt of a RUN request will be considered a protocol violation and will lead to connection closure.

Examples

Synopsis
RUN "query" {parameters} {extra}
Example 1
RUN "RETURN $x AS x" {"x": 1} {"bookmarks": [], "tx_timeout": 123, "tx_metadata": {"log": "example_message"}, "mode": "r"}
Example 2
RUN "RETURN $x AS x" {"x": 1} {}
Example 3
RUN "CALL dbms.procedures()" {} {}
Example 3
RUN "RETURN 42" {} {"notifications_minimum_severity": "WARNING", "notifications_disabled_categories": ["HINT", "GENERIC"]}

Server response SUCCESS

A SUCCESS message response indicates that the client is permitted to exchange further messages.

The following fields are defined for inclusion in the SUCCESS metadata.

  • fields::List<String>, the fields of the return result. e.g. [“name”, “age”, …]

  • t_first::Integer, the time, specified in ms, which the first record in the result stream is available after.

For Explicit Transaction (BEGIN+RUN):

  • qid::Integer specifies the server assigned statement ID to reference the server side result-set with commencing BEGIN+RUN+PULL and BEGIN+RUN+DISCARD messages. Introduced in bolt 4.0

Example v3+
SUCCESS {"fields": ["x"], "t_first": 123}
Example v4.0+
SUCCESS {"fields": ["x"], "t_first": 123, "qid": 7000}

For v1 and v2, if a RUN request has been successfully received and is considered valid by the server, the server should respond with a SUCCESS message and enter the STREAMING state. The server may attach metadata to the message to provide header detail for the results that follow. Clients should not consider a SUCCESS response to indicate completion of the execution of that query, merely acceptance of it. The following fields are defined for inclusion in the metadata:

  • `fields` (e.g. ["name", "age"])

  • `result_available_after` (e.g. 123)

Example v1 and v2
SUCCESS {"fields": ["x"], "result_available_after": 123}

Server response IGNORED

Example
IGNORED

Server response FAILURE

Example
FAILURE {"code": "Example.Failure.Code", "message": "example failure"}

Request message DISCARD

Introduced in bolt 1

The DISCARD message requests that the remainder of the result stream should be thrown away.

In v1, v2 and v3, this message is called DISCARD_ALL, has no fields and issues a request to discard the outstanding result and return to a READY state. A receiving server should not abort the request but continue to process it without streaming any detail messages back to the client.

Signature: 2F

Fields:
extra::Dictionary(
  n::Integer,
  qid::Integer
)
  • extra contains additional options. Introduced in bolt 4.0

    • The n specifies how many records to throw away. n=-1 will throw away all records. n has no default and must be present.

    • The qid (query identification) specifies for which statement the operation should be carried out (Explicit Transaction only). qid=-1 can be used to denote the last executed statement. Default: -1.

Detail messages:

No detail messages should be returned.

Valid summary messages:

  • SUCCESS

  • IGNORED

  • FAILURE

Examples

Synopsis
DISCARD {extra}
Example 1
DISCARD {"n": -1, "qid": -1}
Example 2
DISCARD {"n": 1000}
Example 3 v1, v2 or v3
DISCARD_ALL

In version 1 and 2, the server must be in a STREAMING or STREAMING_TX (v3+) state to be able to successfully process a DISCARD request. If the server is in a FAILED state or INTERRUPTED state, the request will be IGNORED. For any other states, receipt of a DISCARD request will be considered a protocol violation and will lead to connection closure.

Server response SUCCESS

  • has_more::Boolean, true if there are no more records to stream. If this field is not present, it should be considered to default to false. Introduced in bolt 4.0

Or in the case that has_more is false:

  • bookmark::String, the bookmark after committing this transaction (Autocommit Transaction only).

  • t_last::Integer, the time, specified in ms, which the last record in the result stream is consumed after. Introduced in bolt 3

  • result_consumed_after::Integer, same as t_last. Removed after bolt 2

  • type::String, the type of the statement, e.g. "r" for read-only statement, "w" for write-only statement, "rw" for read-and-write, and "s" for schema only. Introduced in bolt 3

  • stats::Dictionary, counter information, such as db-hits etc. Introduced in bolt 3

  • plan::Dictionary, plan result. Introduced in bolt 3

  • profile::Dictionary, profile result. Introduced in bolt 3

  • notifications::List<Dictionary>, a list of all notifications generated during execution of this statement. May be omitted if no notifications exist. In v3, this field is notifications::Dictionary. Introduced in bolt 3

  • db::String, the database name where the query was executed. Introduced in bolt 4.0

Example 1 v4+
SUCCESS {"has_more": true}
Example 2 v4+
SUCCESS {"bookmark": "example-bookmark:1", "db": "example_database"}
Example v3
SUCCESS {"bookmark": "example-bookmark:1"}

In version 1 and 2, if a DISCARD_ALL request has been successfully received, the server should respond with a SUCCESS message and enter the READY state.

Example v1 and v2
SUCCESS {"bookmark": "example_bookmark_identifier", "result_consumed_after": 123}

Request message PULL

The PULL message requests data from the remainder of the result stream.

In v1, v2, and v3, this message is called PULL_ALL and has no fields. In v1 and v2, this message issues a request to stream the outstanding result back to the client, before returning to a READY state. Result detail consists of zero or more detail messages being sent before the summary message. This version of the protocol defines one such detail message, namely RECORD (described below).

Signature: 3F

Fields:
extra::Dictionary(
  n::Integer,
  qid::Integer
)
  • extra contains additional options. Introduced in bolt 4.0

    • The n specifies how many records to fetch. n=-1 will fetch all records. n has no default and must be present.

    • The qid (query identification) specifies for which statement the operation should be carried out (Explicit Transaction only). qid=-1 can be used to denote the last executed statement. Default: -1.

Detail messages:

Zero or more RECORD.

Valid summary messages:

  • SUCCESS

  • IGNORED

  • FAILURE

Examples

Synopsis
PULL {extra}
For v1, v2, and v3
PULL_ALL
Example 1
PULL {"n": -1, "qid": -1}
Example 2
PULL {"n": 1000}
Example v1, v2, and v3
PULL_ALL

Server response SUCCESS

The following fields are defined for inclusion in the SUCCESS metadata:

  • has_more::Boolean, true if there are more records to stream. If this field is not present it should be considered to default to false.

Or in the case that has_more is false:

  • bookmark::String, the bookmark after committing this transaction (Autocommit Transaction only).

  • t_last::Integer, the time, specified in ms, which the last record in the result stream is consumed after. Introduced in bolt 3

  • result_consumed_after::Integer, same as t_last. Removed after bolt 2

  • type::String, the type of the statement, e.g. "r" for read-only statement, "w" for write-only statement, "rw" for read-and-write, and "s" for schema only. Introduced in bolt 3

  • stats::Dictionary, counter information, such as db-hits etc. Introduced in bolt 3

  • plan::Dictionary, plan result. Introduced in bolt 3

  • profile::Dictionary, profile result. Introduced in bolt 3

  • notifications::List<Dictionary>, a list of all notifications generated during execution of this statement. May be omitted if no notifications exist. In v3, this field is notifications::Dictionary. Introduced in bolt 3

  • db::String, the database name where the query was executed. Introduced in bolt 4.0

Example
SUCCESS {"bookmark": "example-bookmark:1", "t_last": 123}
Example v1 and v2
SUCCESS {"bookmark": "example_bookmark_identifier", "result_consumed_after": 123}

Server response IGNORED

For v1 and v2, a server that receives a PULL_ALL request while in FAILED state or INTERRUPTED state, should respond with an IGNORED message and discard the request without processing it. No state change should occur.

Example (all versions)
IGNORED

Server response FAILURE

For v1 and v2, a PULL_ALL message request cannot be processed successfully, the server should respond with a FAILURE message and enter the FAILED state. The server may attach metadata to the message to provide more detail on the nature of the failure.

Example (all versions)
FAILURE {"code": "Example.Failure.Code", "message": "example failure"}

Server response RECORD (in v1 and v2)

Zero or more RECORD messages may be returned in response to a PULL_ALL prior to the trailing summary message. Each record carries with it a list of values which form the data content of the record. The order of the values within the list should be meaningful to the client, perhaps based on a requested ordering for that result, but no guarantees should be made around the order of records within the result. A record should only be considered valid if followed by a SUCCESS summary message. Until this summary has been received, the record’s validity should be considered tentative.

Example
RECORD [1, 2, 3]

Request massage BEGIN

Introduced in bolt 1

The BEGIN message request the creation of a new Explicit Transaction. This message should then be followed by a RUN message. The Explicit Transaction is closed with either the COMMIT message or ROLLBACK message.

In version 5.2, notifications_minimum_severity::String and notifications_disabled_categories::List<String> were added to be able to control the notification config. Disabling categories or severities allows the server to skip analysis for those, which can speed up query execution.

Signature: 11

Fields:
extra::Dictionary(
  bookmarks::List<String>,
  tx_timeout::Integer,
  tx_metadata::Dictionary,
  mode::String,
  db::String,
  imp_user::String,
  notifications_minimum_severity::String,
  notifications_disabled_categories::List<String>
)
  • The bookmarks is a list of strings containing some kind of bookmark identification e.g ["neo4j-bookmark-transaction:1", "neo4j-bookmark-transaction:2"]. Default: [].

  • The tx_timeout is an integer in that specifies a transaction timeout in ms. Default: server-side configured timeout.

  • The tx_metadata is a dictionary that can contain some metadata information, mainly used for logging. Default: null.

  • The mode specifies what kind of server the RUN message is targeting. For write access use "w" and for read access use "r". Defaults to write access if no mode is sent. Default: "w".

  • The db specifies the database name for multi-database to select where the transaction takes place. null and "" denote the server-side configured default database. Default: null. Introduced in bolt 4.0

  • The imp_user key specifies the impersonated user which executes this transaction. null denotes no impersonation (execution takes place as the current user). Default: null. Introduced in bolt 4.4

  • The notifications_minimum_severity specifies the minimum severity a notification needs to have to be returned. Please see the Cypher documentation for acceptable entries, with the special value "OFF" added to the protocol, which disables all notifications. Sending null will make the server use whatever was specified in the HELLO message of the current connection. Default: null. Introduced in bolt 5.2

  • The notifications_disabled_categories is a list of notification categories that will not be returned. Please see the Cypher documentation for available categories. Sending null will make the server use whatever was specified in the HELLO message of the current connection. Default: null. Introduced in bolt 5.2

Detail messages:

No detail messages.

Valid summary messages:

  • SUCCESS

  • IGNORED

  • FAILURE

Examples

Synopsis
BEGIN {extra}
Example 1
BEGIN {"tx_timeout": 123, "mode": "r", "db": "example_database", "tx_metadata": {"log": "example_log_data"}, "imp_user" : "bob"}
Example 2
BEGIN {"db": "example_database", "tx_metadata": {"log": "example_log_data"}, "bookmarks": ["example-bookmark:1", "example-bookmark2"]}
Example 3
BEGIN {"notifications_minimum_severity": "WARNING", "notifications_disabled_categories": ["HINT", "GENERIC"]}

Server response SUCCESS

Example
SUCCESS {}

Server response IGNORED

Example
IGNORED

Server response FAILURE

Example
FAILURE {"code": "Example.Failure.Code", "message": "example failure"}

Request message COMMIT

The COMMIT message request that the Explicit Transaction is done.

The COMMIT message does not exist in v1 and v2.

Signature: 12

Fields: No fields.

Detail messages:

No detail messages.

Valid summary messages:

  • SUCCESS

  • IGNORED

  • FAILURE

Examples

Synopsis
COMMIT
Example
COMMIT

Server response SUCCESS

A SUCCESS message response indicates that the Explicit Transaction was completed:

  • bookmark::String, the bookmark after committing this transaction.

Example
SUCCESS {"bookmark": "example-bookmark:1"}

Server response IGNORED

Example
IGNORED

Server response FAILURE

Example
FAILURE {"code": "Example.Failure.Code", "message": "example failure"}

Request message ROLLBACK

The ROLLBACK message requests that the Explicit Transaction rolls back.

The ROLLBACK message does not exist in v1 and v2.

Signature: 13

Fields: No fields.

Detail messages:

No detail messages.

Valid summary messages:

  • SUCCESS

  • IGNORED

  • FAILURE

Examples

Synopsis
ROLLBACK
Example
ROLLBACK

Server response SUCCESS

A SUCCESS message response indicates that the Explicit Transaction was rolled back.

Example
SUCCESS

Server response IGNORED

Example
IGNORED

Server response FAILURE

Example
FAILURE {"code": "Example.Failure.Code", "message": "example failure"}

Request message ROUTE

Introduced in bolt 4.3

The ROUTE instructs the server to return the current routing table. In previous versions there was no explicit message for this and a procedure had to be invoked using Cypher through the RUN and PULL messages.

This message can only be sent after successful authentication and outside of transactions.

Signature: 66

Fields:
routing::Dictionary,
bookmarks::List<String>,
db::String,
extra::Dictionary(
  db::String,
  imp_user::String,
)

Note that in v4.4, the db parameter is migrated into a dedicated dictionary named extra that also includes the imp_user and thus, in v4.3 the fields are:

routing::Dictionary,
bookmarks::List<String>,
db::String
  • The routing field should contain routing context information and the address field that should contain the address that the client initially tries to connect with e.g. "x.example.com:9001". Key-value entries in the routing context should correspond exactly to those in the original URI query string.

  • The bookmarks is a list of strings containing some kind of bookmark identification e.g ["neo4j-bookmark-transaction:1", "neo4j-bookmark-transaction:2"].

  • The db specifies the database name for multi-database to select where the transaction takes place. null denotes the server-side configured default database. Removed after bolt 4.3

  • extra contains additional options. Introduced in bolt 4.4

    • db as above. Default: null.

    • The imp_user specifies the impersonated user for the purposes of resolving their home database. null denotes no impersonation (execution takes place as the current user). Default: null.

Detail messages:

No detail messages should be returned.

Valid summary messages:

  • SUCCESS

  • IGNORED

  • FAILURE

Examples

Synopsis
ROUTE {routing} [bookmarks] {extra}
Example v4.4+
ROUTE {"address": "x.example.com:9001", "policy": "example_policy_routing_context", "region": "example_region_routing_context"} ["neo4j-bookmark-transaction:1", "neo4j-bookmark-transaction:2"] {"db": "example_database", "imp_user": "bob"}
Example v4.3
ROUTE {"address": "x.example.com:7687"} [] null

Server response SUCCESS

A SUCCESS message response indicates that the client is permitted to exchange further messages. The following fields are defined for inclusion in the SUCCESS metadata:

  • rt::Dictionary(ttl::Integer, db::String, servers::List<Dictionary(addresses::List<String>, role::String)>), the current routing table.

    • ttl::Integer specifies for how many seconds this routing table should be considered valid.

    • db::String identifies the database for which this routing table applies. Introduced in bolt 4.4

    • servers have three elements of the type Dictionary(addresses::List<String>, role::String), where role is one of "ROUTE", "READ", "WRITE" for exactly one entry each.

Example v4.4+
SUCCESS {
    "rt": {"ttl": 1000,
           "db": "foo",
           "servers": [{"addresses": ["localhost:9001"], "role": "ROUTE"},
                       {"addresses": ["localhost:9010", "localhost:9012"], "role": "READ"},
                       {"addresses": ["localhost:9020", "localhost:9022"], "role": "WRITE"}]}
}
Example v4.3
SUCCESS {
    "rt": {"ttl": 1000,
           "servers": [{"addresses": ["localhost:9001"], "role": "ROUTE"},
                       {"addresses": ["localhost:9010", "localhost:9012"], "role": "READ"},
                       {"addresses": ["localhost:9020", "localhost:9022"], "role": "WRITE"}]}
}

Server message IGNORED

Example
IGNORED

Server message FAILURE

Example
FAILURE {"code": "Example.Failure.Code", "message": "example failure"}

Summary message SUCCESS

The SUCCESS message indicates that the corresponding request has succeeded as intended. It may contain metadata relating to the outcome. Metadata keys are described in the section of this document relating to the message that began the exchange.

Signature: 70

Fields:
metadata::Dictionary

Examples

Synopsis
SUCCESS {metadata}
Example
SUCCESS {"example": "see specific message for server response metadata"}

Summary message IGNORED

The IGNORED message indicates that the corresponding request has not been carried out.

Signature: 7E

Fields: No fields.

Examples

Synopsis
IGNORED
Example
IGNORED

Summary message FAILURE

Signature: 7F

Fields:
metadata::Dictionary(
  code::String,
  message::String
)

Examples

Synopsis
FAILURE {metadata}
Example
FAILURE {"code": "Example.Failure.Code", "message": "example failure"}

Detail message RECORD

A RECORD message carries a sequence of values corresponding to a single entry in a result.

Signature: 71

These messages are currently only ever received in response to a PULL (PULL_ALL in v1, v2, and v3) message and will always be followed by a summary message.

Examples

Synopsis
RECORD [data]
Example 1
RECORD ["1", "2", "3"]
Example 2
RECORD [{"point": [1, 2]}, "example_data", 123]

Summary of changes per version

The sections below list the changes of messages compared to the previous version. Please also check for changes in Structure Semantics.

Version 5.4

  • A new message TELEMETRY is added.

Version 5.3

  • A new field bolt_agent is added to the HELLO message’s extra dictionary.

Version 5.2

  • HELLO, BEGIN and RUN messages now accept notifications options notifications_minimum_severity and notifications_disabled_categories.

Version 5.1

  • HELLO message no longer accepts authentication.

  • LOGON message has been added and accepts authentication.

  • LOGOFF message has been added.

Version 5

  • No changes from version 4.4

Version 4.4

  • The db parameter within the ROUTE message is migrated into a dedicated dictionary named extra.

  • An imp_user parameter is added to the meta fields within ROUTE, RUN and BEGIN messages respectively.

Version 4.3

  • NOOP chunks may now be transmitted in all connection states when a connection remains in idle for extended periods of time while the server is busy processing a request.

  • An additional hints dictionary is added to the metadata property of the SUCCESS structure transmitted in response to the HELLO command in order to provide optional configuration hints to drivers.

  • A new message ROUTE to query the routing table is added.

Version 4.2

No changes compared to version 4.1.

Version 4.1

  • The HELLO message, defines the sub-field routing::Dictionary(address::String) to indicate if server side routing should be performed and can include routing context data.

  • Support for NOOP chunk (empty chunk). Both server and client should support this.

Version 4.0

  • DISCARD_ALL message renamed to DISCARD and introduced new fields.

  • PULL_ALL message renamed to PULL and introduced new fields.

  • The BEGIN message now have a field db::String to specify a database name.

  • The RUN message now have a field db::String to specify a database name.

  • Explicit Transaction (BEGIN+RUN) can now get a server response with a SUCCESS and metadata key qid (query identification).

  • The DISCARD message can now discard an arbitrary number of records. New fields n and qid.

  • The DISCARD message can now get a server response with a SUCCESS and metadata key has_more.

  • The PULL message can now fetch an arbitrary number of records. New fields n and qid.

  • The PULL message can now get a server response with a SUCCESS and metadata key has_more.

Version 3

  • The INIT request message is replaced with HELLO message.

  • The ACK_FAILURE request message is removed. Use RESET message instead.

  • Added extra::Dictionary field to RUN message.

  • Added extra::Dictionary field to BEGIN message.

  • New HELLO request message.

  • New GOODBYE request message.

  • New BEGIN request message.

  • New COMMIT request message.

  • New ROLLBACK request message.

  • New RESET request message.

Version 2

No changes compared to version 1.