Understanding MQTT Messages: An In-Depth Guide to CONNECT and CONNACK Messages in MQTT 5.0

In the introduction to MQTT 5.0 messages, we discussed that MQTT messages consist of three parts: a fixed header, a variable header, and a payload, as well as general concepts like variable byte integers and attributes in MQTT messages. Now, we will delve further into the composition of various types of messages based on their actual use. First, we will focus on messages used to establish an MQTT connection.

If we want to use MQTT for communication, the first step is inevitably to establish an MQTT connection, and establishing an MQTT connection requires two control messages: CONNECT and CONNACK messages. The CONNECT message is the first control message sent by the client to the server to initiate a connection request after a network connection is established. The server will return a CONNACK message to inform the client of the connection result.

Message Example

We use the MQTTX CLI to initiate a connection to a public MQTT server. In this connection, we set the protocol version to MQTT 5.0, Clean Start to 1, Session Expiry Interval to 300 seconds, Keep Alive to 60, and the username and password to admin and public, respectively. The corresponding MQTTX CLI command is:

mqttx conn --hostname broker.emqx.io --mqtt-version 5 \  --session-expiry-interval 300 --keepalive 60 --username admin --password public

Below is the CONNECT message sent by MQTTX CLI captured using Wireshark. On Linux, you can first use the tcpdump command to capture the message, then import it into Wireshark to view it:

10 2f 00 04 4d 51 54 54 05 c2 00 3c 05 11 00 00 01 2c 00 0e 6d 71 74 74 78 5f 30 63 36 36 38 64 30 64 00 05 61 64 6d 69 6e 00 06 70 75 62 6c 69 63

However, this is a series of hexadecimal bytes that are difficult to understand unless they are converted to the following format:

 MQTT messages

Similarly, we captured the CONNACK message returned by the public MQTT server:

20 13 00 00 10 27 00 10 00 00 25 01 2a 01 29 01 22 ff ff 28 01

After parsing this series of message data, we can see that the Reason Code for the CONNACK message is 0, indicating a successful connection, and many subsequent properties list the functionalities supported by the server, such as the maximum packet size and whether it supports retained messages:

 MQTT messages

Of course, Wireshark has already listed the values of each field in the message for us. By introducing the structure of CONNECT and CONNACK messages below and combining it with Wireshark’s capture results, you will quickly master these two messages:

CONNECT Message Structure

Fixed Header

In the fixed header of the CONNECT message, the value of the message type field in the high 4 bits of the first byte must be 1 (0b0001), and the low 4 bits of the first byte are fixed to all 0.

Therefore, the value of the first byte of the CONNECT message must be 0x10, which we can use to determine whether a message is a CONNECT message.

Variable Header

The variable header of the CONNECT message contains the following fields in order:

  • Protocol Name: This is a UTF-8 encoded string used to represent the protocol name. In MQTT, the first two bytes of a UTF-8 encoded string are uniformly used to indicate the length of the actual character data that follows. The protocol name in MQTT 3.1.1 and MQTT 5.0 is fixed as MQTT, so the complete content represented by hexadecimal bytes is 00 04 4d 51 54 54, where 4d 51 54 54 corresponds to the ASCII value of the string MQTT. In the earliest MQTT 3.1, the protocol name was MQIsdp, corresponding to 00 06 4d 51 49 73 64 70.
  • Protocol Version: This is a single-byte unsigned integer used to represent the protocol version. There are currently only three possible values: 3 for MQTT 3.1, 4 for MQTT 3.1.1, and 5 for MQTT 5.0.
  • Connect Flags: Connection flags, which contain multiple parameters for controlling connection behavior or indicating whether certain fields in the payload exist, all within a single byte.

  • User Name Flag: Indicates whether the payload contains a username field.
  • Password Flag: Indicates whether the payload contains a password field.
  • Will Retain: Indicates whether the will message is a retained message.
  • Will QoS: Indicates the QoS of the will message.
  • Will Flag: Indicates whether the payload contains fields related to the will message.
  • Clean Start: Indicates whether the current connection is a new session or a continuation of an existing session, determining whether the server will directly create a new session or attempt to reuse an existing one.
  • Reserved: This is a reserved bit, and its value must be 0.
  • Keep Alive: This is a two-byte unsigned integer used to represent the maximum time interval between two adjacent control messages sent by the client.
  • Properties: The table below lists all available properties of the CONNECT message.

Identifier

Property Name

Type

0x11

Session Expiry Interval

Four-byte integer

0x21

Receive Maximum

Two-byte integer

0x27

Maximum Packet Size

Four-byte integer

0x22

Topic Alias Maximum

Two-byte integer

0x19

Request Response Information

Single byte

0x17

Request Problem Information

Single byte

0x26

User Property

UTF-8 string pair

0x15

Authentication Method

UTF-8 encoded string

0x16

Authentication Data

Binary data

Payload

In the payload of the CONNECT message, fields other than the Client ID are optional. Their existence depends on the value of the corresponding flags in the Connect Flags of the variable header. However, if these fields exist, they must appear in the order of Client ID, Will Properties, Will Topic, Will Payload, User Name, and Password.

CONNACK Message Structure

Fixed Message

The value of the high 4 bits of the first byte in the fixed header is 2 (0b0010), indicating that this is a CONNACK message.

Variable Header

The variable header of the CONNACK message contains the following fields in order:

  • Connect Acknowledge Flags:
    • Reserved (Bit 7 – 1): Reserved bit, must be set to 0.
    • Session Present (Bit 0): Indicates whether the server is using an existing session to resume communication with the client. The Session Present can only be 1 if the client set Clean Start to 0 in the CONNECT connection.
  • Reason Code: Indicates the connection result. The table below lists some common Reason Codes in CONNACK messages; a complete list can be found in the MQTT 5.0 Reason Code reference.

Value

Reason Code Name

Description

0x00

Success

The connection was accepted.

0x81

Malformed Packet

The server could not correctly parse the CONNECT message according to protocol specifications, such as the reserved bit was not set to 0 as required.

0x82

Protocol Error

The CONNECT message can be correctly parsed, but its content does not conform to protocol specifications, such as the Will Topic field value is not a valid MQTT topic.

0x84

Unsupported Protocol Version

The server does not support the MQTT protocol version requested by the client.

0x85

Client Identifier not valid

The Client ID is a valid string but is not accepted by the server, such as when the Client ID exceeds the maximum length allowed by the server.

0x86

Bad User Name or Password

The client was refused connection due to incorrect username or password.

0x95

Packet too large

The CONNECT message exceeded the maximum length allowed by the server, possibly because it carried a large Will message.

0x8A

Banned

The client is banned from logging in. For example, the server detected abnormal connection behavior from the client, so it added the client’s Client ID or IP address to a blacklist, or the administrator manually banned the client. Of course, these usually depend on the server’s specific implementation.

  • Properties: The table below lists all available properties of the CONNACK message.

Identifier

Property Name

Type

0x11

Session Expiry Interval

Four-byte integer

0x21

Receive Maximum

Two-byte integer

0x24

Maximum QoS

Single byte

0x25

Retain Available

Single byte

0x27

Maximum Packet Size

Four-byte integer

0x12

Assigned Client Identifier

UTF-8 encoded string

0x22

Topic Alias Maximum

Two-byte integer

0x1F

Reason String

UTF-8 encoded string

0x26

User Property

UTF-8 string pair

0x28

Wildcard Subscription Available

Single byte

0x29

Subscription Identifier Available

Single byte

0x2A

Shared Subscription Available

Single byte

0x13

Server Keep Alive

Two-byte integer

0x1A

Response Information

UTF-8 encoded string

0x1C

Server Reference

UTF-8 encoded string

0x15

Authentication Method

UTF-8 encoded string

0x16

Authentication Data

Binary data

Payload

The CONNACK message does not contain a payload.

Summary

CONNECT is the first MQTT message sent by the client to the server after establishing a network connection, and CONNACK is the response message to CONNECT, indicating the connection result through the reason code.

The client and server need to use CONNECT and CONNACK messages to complete the necessary information exchange, such as the client’s protocol version, Client ID, username, password, and whether the server has a corresponding session, the maximum packet size supported, and the maximum QoS level, etc.

The above is an introduction to MQTT CONNECT and CONNACK messages. In future articles, we will continue to study the structure and composition of PUBLISH, DISCONNECT, and other messages.