Reference

Client Protocol

The protocol used to communicate between the NATS server and clients is a simple, text-based protocol. The default transport is a TCP/IP socket, however WebSockets are supported as well as a UNIX domain socket if the server is embedded within a Go process.

Overview

The following table briefly describes the NATS protocol messages. NATS protocol operation names are case insensitive, thus SUB foo 1␍␊ and sub foo 1␍␊ are equivalent.

MessageSent ByDescription
INFOServerSent to client after initial TCP/IP connection
CONNECTClientSent to server to specify connection information
PUBClientPublish a message to a subject, with optional reply subject
HPUBClientPublish a message to a subject including NATS headers, with optional reply subject
SUBClientSubscribe to a subject (or subject wildcard)
UNSUBClientUnsubscribe (or auto-unsubscribe) from subject
MSGServerDelivers a message payload to a subscriber
HMSGServerDelivers a message payload to a subscriber with NATS headers
PINGBothPING keep-alive message
PONGBothPONG keep-alive response
+OKServerAcknowledges well-formed protocol message in verbose mode
-ERRServerIndicates a protocol error. May cause client disconnect.

The following sections explain each protocol message.

INFO

A client will need to start as a plain TCP connection, then when the server accepts a connection from the client, it will send information about itself, the configuration and security requirements necessary for the client to successfully authenticate with the server and exchange messages.

When using the updated client protocol (see CONNECT below), INFO messages can be sent anytime by the server. This means clients with that protocol level need to be able to asynchronously handle INFO messages.

Syntax

INFO {"option_name":option_value,...}␍␊

The valid options are as follows, encoded as JSON:

NameDescriptionTypePresence
server_idThe unique identifier of the NATS server.stringalways
server_nameThe name of the NATS server.stringalways
versionThe version of NATS.stringalways
goThe version of golang the NATS server was built with.stringalways
hostThe IP address used to start the NATS server, by default this will be 0.0.0.0 and can be configured with -client_advertise host:port.stringalways
portThe port number the NATS server is configured to listen on.intalways
headersWhether the server supports headers.boolalways
max_payloadMaximum payload size, in bytes, that the server will accept from the client.intalways
protoAn integer indicating the protocol version of the server. The server version 1.2.0 sets this to 1 to indicate that it supports the "Echo" feature.intalways
client_idThe internal client identifier in the server. This can be used to filter client connections in monitoring, correlate with error logs, etc...uint64optional
auth_requiredIf this is true, then the client should try to authenticate upon connect.booloptional
tls_requiredIf this is true, then the client must perform the TLS/1.2 handshake. Note, this used to be ssl_required and has been updated along with the protocol from SSL to TLS.booloptional
tls_verifyIf this is true, the client must provide a valid certificate during the TLS handshake.booloptional
tls_availableIf this is true, the client can provide a valid certificate during the TLS handshake.booloptional
connect_urlsList of server urls that a client can connect to.[string]optional
ws_connect_urlsList of server urls that a websocket client can connect to.[string]optional
ldmIf the server supports Lame Duck Mode notifications, and the current server has transitioned to lame duck, ldm will be set to true.booloptional
git_commitThe git hash at which the NATS server was built.stringoptional
jetstreamWhether the server supports JetStream.booloptional
ipThe IP of the server.stringoptional
client_idThe ID of the client.stringoptional
client_ipThe IP of the client.stringoptional
nonceThe nonce for use in CONNECT.stringoptional
clusterThe name of the cluster.stringoptional
domainThe configured NATS domain of the server.stringoptional

connect_urls

The connect_urls field is a list of urls the server may send when a client first connects, and when there are changes to server cluster topology. This field is considered optional, and may be omitted based on server configuration and client protocol level.

When a NATS server cluster expands, an INFO message is sent to the client with an updated connect_urls list. This cloud-friendly feature asynchronously notifies a client of known servers, allowing it to connect to servers not originally configured.

The connect_urls will contain a list of strings with an IP and port, looking like this: "connect_urls":["10.0.0.184:4333","192.168.129.1:4333","192.168.192.1:4333"]

Example

Below you can see a sample connection string from a telnet connection to the demo.nats.io site.

telnet demo.nats.io 4222
Trying 107.170.221.32...
Connected to demo.nats.io.
Escape character is '^]'.
INFO {"server_id":"Zk0GQ3JBSrg3oyxCRRlE09","version":"1.2.0","proto":1,"go":"go1.10.3","host":"0.0.0.0","port":4222,"max_payload":1048576,"client_id":2392}

CONNECT

The CONNECT message is the client version of the INFO message. Once the client has established a TCP/IP socket connection with the NATS server, and an INFO message has been received from the server, the client may send a CONNECT message to the NATS server to provide more information about the current connection as well as security information.

Syntax

CONNECT {"option_name":option_value,...}␍␊

The valid options are as follows, encoded as JSON:

NameDescriptionTypeRequired
verboseTurns on +OK protocol acknowledgements.booltrue
pedanticTurns on additional strict format checking, e.g. for properly formed subjects.booltrue
tls_requiredIndicates whether the client requires an SSL connection.booltrue
auth_tokenClient authorization token.stringif auth_required is true
userConnection username.stringif auth_required is true
passConnection password.stringif auth_required is true
nameClient name.stringfalse
langThe implementation language of the client.stringtrue
versionThe version of the client.stringtrue
protocolSending 0 (or absent) indicates client supports original protocol. Sending 1 indicates that the client supports dynamic reconfiguration of cluster topology changes by asynchronously receiving INFO messages with known servers it can reconnect to.intfalse
echoIf set to false, the server (version 1.2.0+) will not send originating messages from this connection to its own subscriptions. Clients should set this to false only for server supporting this feature, which is when proto in the INFO protocol is set to at least 1.boolfalse
sigIn case the server has responded with a nonce on INFO, then a NATS client must use this field to reply with the signed nonce.stringif nonce received
jwtThe JWT that identifies a user permissions and account.stringfalse
no_respondersEnable quick replies for cases where a request is sent to a topic with no responders.boolfalse
headersWhether the client supports headers.boolfalse
nkeyThe public NKey to authenticate the client. This will be used to verify the signature (sig) against the nonce provided in the INFO message.stringfalse

Example

Here is an example from the default string of the Go client:

CONNECT {"verbose":false,"pedantic":false,"tls_required":false,"name":"","lang":"go","version":"1.2.2","protocol":1}␍␊

Most clients set verbose to false by default. This means that the server should not confirm each message it receives on this connection with a +OK back to the client.

PUB

The PUB message publishes the message payload to the given subject name, optionally supplying a reply subject. If a reply subject is supplied, it will be delivered to eligible subscribers along with the supplied payload. Note that the payload itself is optional. To omit the payload, set the payload size to 0, but the second CRLF is still required.

Syntax

PUB <subject> [reply-to] <#bytes>␍␊[payload]␍␊

where:

NameDescriptionTypeRequired
subjectThe destination subject to publish to.stringtrue
reply-toThe reply subject that subscribers can use to send a response back to the publisher/requestor.stringfalse
#bytesThe payload size in bytes.inttrue
payloadThe message payload data.stringfalse

Example

To publish the ASCII string message payload "Hello NATS!" to subject FOO:

PUB FOO 11␍␊Hello NATS!␍␊

To publish a request message "Knock Knock" to subject FRONT.DOOR with reply subject JOKE.22:

PUB FRONT.DOOR JOKE.22 11␍␊Knock Knock␍␊

To publish an empty message to subject NOTIFY:

PUB NOTIFY 0␍␊␍␊

HPUB

The HPUB message is the same as PUB but extends the message payload to include NATS headers. Note that the payload itself is optional. To omit the payload, set the total message size equal to the size of the headers. Note that the trailing CR+LF is still required.

NATS headers are similar, in structure and semantics, to HTTP headers as name: value pairs including supporting multi-value headers. Headers can be mixed case and NATS will preserve case between message publisher and message receiver(s). See also ADR-4 NATS Message Headers.

Syntax

HPUB <subject> [reply-to] <#header bytes> <#total bytes>␍␊[headers]␍␊␍␊[payload]␍␊

where:

NameDescriptionTypeRequired
subjectThe destination subject to publish to.stringtrue
reply-toThe reply subject that subscribers can use to send a response back to the publisher/requestor.stringfalse
#header bytesThe size of the headers section in bytes including the ␍␊␍␊ delimiter before the payload.inttrue
#total bytesThe total size of headers and payload sections in bytes.inttrue
headersHeader version NATS/1.0␍␊ followed by one or more name: value pairs, each separated by ␍␊.stringfalse
payloadThe message payload data.stringfalse

Example

To publish the ASCII string message payload "Hello NATS!" to subject FOO with one header Bar with value Baz:

HPUB FOO 22 33␍␊NATS/1.0␍␊Bar: Baz␍␊␍␊Hello NATS!␍␊

To publish a request message "Knock Knock" to subject FRONT.DOOR with reply subject JOKE.22 and two headers:

HPUB FRONT.DOOR JOKE.22 45 56␍␊NATS/1.0␍␊BREAKFAST: donut␍␊LUNCH: burger␍␊␍␊Knock Knock␍␊

To publish an empty message to subject NOTIFY with one header Bar with value Baz:

HPUB NOTIFY 22 22␍␊NATS/1.0␍␊Bar: Baz␍␊␍␊␍␊

To publish a message to subject MORNING MENU with one header BREAKFAST having two values and payload "Yum!"

HPUB MORNING.MENU 47 51␍␊NATS/1.0␍␊BREAKFAST: donut␍␊BREAKFAST: eggs␍␊␍␊Yum!␍␊

SUB

SUB initiates a subscription to a subject, optionally joining a distributed queue group.

Syntax

SUB <subject> [queue group] <sid>␍␊

where:

NameDescriptionTypeRequired
subjectThe subject name to subscribe to.stringtrue
queue groupIf specified, the subscriber will join this queue group.stringfalse
sidA unique alphanumeric subscription ID, generated by the client.stringtrue

Example

To subscribe to the subject FOO with the connection-unique subscription identifier (sid) 1:

SUB FOO 1␍␊

To subscribe the current connection to the subject BAR as part of distribution queue group G1 with sid 44:

SUB BAR G1 44␍␊

UNSUB

UNSUB unsubscribes the connection from the specified subject, or auto-unsubscribes after the specified number of messages has been received.

Syntax

UNSUB <sid> [max_msgs]␍␊

where:

NameDescriptionTypeRequired
sidThe unique alphanumeric subscription ID of the subject to unsubscribe from.stringtrue
max_msgsA number of messages to wait for before automatically unsubscribing.intfalse

Example

The following examples concern subject FOO which has been assigned sid 1. To unsubscribe from FOO:

UNSUB 1␍␊

To auto-unsubscribe from FOO after 5 messages have been received:

UNSUB 1 5␍␊

MSG

The MSG protocol message is used to deliver an application message to the client.

Syntax

MSG <subject> <sid> [reply-to] <#bytes>␍␊[payload]␍␊

where:

NameDescriptionTypePresence
subjectSubject name this message was received on.stringalways
sidThe unique alphanumeric subscription ID of the subject.stringalways
reply-toThe subject on which the publisher is listening for responses.stringoptional
#bytesSize of the payload in bytes.intalways
payloadThe message payload data.stringoptional

Example

The following message delivers an application message from subject FOO.BAR:

MSG FOO.BAR 9 11␍␊Hello World␍␊

To deliver the same message along with a reply subject:

MSG FOO.BAR 9 GREETING.34 11␍␊Hello World␍␊

HMSG

The HMSG message is the same as MSG, but extends the message payload with headers. See also ADR-4 NATS Message Headers.

Syntax

HMSG <subject> <sid> [reply-to] <#header bytes> <#total bytes>␍␊[headers]␍␊␍␊[payload]␍␊

where:

NameDescriptionTypePresence
subjectSubject name this message was received on.stringalways
sidThe unique alphanumeric subscription ID of the subject.stringalways
reply-toThe subject on which the publisher is listening for responses.stringoptional
#header bytesThe size of the headers section in bytes including the ␍␊␍␊ delimiter before the payload.intalways
#total bytesThe total size of headers and payload sections in bytes.intalways
headersHeader version NATS/1.0␍␊ followed by one or more name: value pairs, each separated by ␍␊.stringoptional
payloadThe message payload data.stringoptional

Example

The following message delivers an application message from subject FOO.BAR with a header:

HMSG FOO.BAR 34 45␍␊NATS/1.0␍␊FoodGroup: vegetable␍␊␍␊Hello World␍␊

To deliver the same message along with a reply subject:

HMSG FOO.BAR 9 BAZ.69 34 45␍␊NATS/1.0␍␊FoodGroup: vegetable␍␊␍␊Hello World␍␊

PING/PONG

PING and PONG implement a simple keep-alive mechanism between client and server. Once a client establishes a connection to the NATS server, the server will continuously send PING messages to the client at a configurable interval. If the client fails to respond with a PONG message within the configured response interval, the server will terminate its connection. If your connection stays idle for too long, it is cut off.

If the server sends a ping request, you can reply with a pong message to notify the server that you are still interested. You can also ping the server and will receive a pong reply. The ping/pong interval is configurable.

The server uses normal traffic as a ping/pong proxy, so a client that has messages flowing may not receive a ping from the server.

Syntax

PING␍␊

PONG␍␊

Example

The following example shows the demo server pinging the client and finally shutting it down.

telnet demo.nats.io 4222

Trying 107.170.221.32...
Connected to demo.nats.io.
Escape character is '^]'.
INFO {"server_id":"Zk0GQ3JBSrg3oyxCRRlE09","version":"1.2.0","proto":1,"go":"go1.10.3","host":"0.0.0.0","port":4222,"max_payload":1048576,"client_id":2392}
PING
PING
-ERR 'Stale Connection'
Connection closed by foreign host.

+OK/ERR

When the verbose connection option is set to true (the default value), the server acknowledges each well-formed protocol message from the client with a +OK message. Most NATS clients set the verbose option to false using the CONNECT message

The -ERR message is used by the server indicate a protocol, authorization, or other runtime connection error to the client. Most of these errors result in the server closing the connection.

Handling of these errors usually has to be done asynchronously.

Syntax

+OK␍␊
-ERR <error message>␍␊

Errors

The table below lists the possible errors that can occur. Some protocol errors result in the server closing the connection. Upon receiving these errors, the connection is no longer valid and the client should clean up relevant resources. This is denoted by the Recoverable column.

ErrorDescriptionRecoverable
Unknown Protocol OperationUnknown protocol errorNo
Attempted To Connect To Route PortClient attempted to connect to a route port instead of the client portNo
Authorization ViolationClient failed to authenticate to the server with credentials specified in the CONNECT messageNo
Authorization TimeoutClient took too long to authenticate to the server after establishing a connection (default 1 second)No
Invalid Client ProtocolClient specified an invalid protocol version in the CONNECT messageNo
Maximum Control Line ExceededMessage destination subject and reply subject length exceeded the maximum control line value specified by the max_control_line server option. The default is 1024 bytes.No
Parser ErrorCannot parse the protocol message sent by the clientNo
Secure Connection - TLS RequiredThe server requires TLS and the client does not have TLS enabled.No
Stale ConnectionThe server hasn't received a message from the client, including a PONG in too long.No
Maximum Connections ExceededThis error is sent by the server when creating a new connection and the server has exceeded the maximum number of connections specified by the max_connections server option. The default is 64k.No
Slow ConsumerThe server pending data size for the connection has reached the maximum size (default 10MB).No
Maximum Payload ViolationClient attempted to publish a message with a payload size that exceeds the max_payload size configured on the server. This value is supplied to the client upon connection in the initial INFO message. The client is expected to do proper accounting of byte size to be sent to the server in order to handle this error synchronously.No
Invalid SubjectClient sent a malformed subject (e.g. SUB foo. 90)Yes
Permissions Violation for Subscription to <subject>The user specified in the CONNECT message does not have permission to subscribe to the subject.Yes
Permissions Violation for Publish to <subject>The user specified in the CONNECT message does not have permissions to publish to the subject.Yes
Previous
Protocols