2 MQTT Control Packet format
2.1 Structure of an MQTT Control Packet
The MQTT protocol operates by exchanging a series of MQTT Control Packets in a defined way. This section describes the format of these packets.
An MQTT Control Packet consists of up to three parts, always in the following order as shown below.
Figure 2‑1 Structure of an MQTT Control Packet
Fixed Header, present in all MQTT Control Packets |
Variable Header, present in some MQTT Control Packets |
Payload, present in some MQTT Control Packets |
2.1.1 Fixed Header
Each MQTT Control Packet contains a Fixed Header as shown below.
Figure 2‑2 Fixed Header format
Bit |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
byte 1 |
MQTT Control Packet type |
Flags specific to each MQTT Control Packet type |
||||||
byte 2… |
Remaining Length |
2.1.2 MQTT Control Packet type
Position: byte 1, bits 7-4.
Represented as a 4-bit unsigned value, the values are shown below.
Table 2‑1 MQTT Control Packet types
Name |
Value |
Direction of flow |
Description |
Reserved |
0 |
Forbidden |
Reserved |
CONNECT |
1 |
Client to Server |
Connection request |
CONNACK |
2 |
Server to Client |
Connect acknowledgment |
PUBLISH |
3 |
Client to Server or Server to Client |
Publish message |
PUBACK |
4 |
Client to Server or Server to Client |
Publish acknowledgment (QoS 1) |
PUBREC |
5 |
Client to Server or Server to Client |
Publish received (QoS 2 delivery part 1) |
PUBREL |
6 |
Client to Server or Server to Client |
Publish release (QoS 2 delivery part 2) |
PUBCOMP |
7 |
Client to Server or Server to Client |
Publish complete (QoS 2 delivery part 3) |
SUBSCRIBE |
8 |
Client to Server |
Subscribe request |
SUBACK |
9 |
Server to Client |
Subscribe acknowledgment |
UNSUBSCRIBE |
10 |
Client to Server |
Unsubscribe request |
UNSUBACK |
11 |
Server to Client |
Unsubscribe acknowledgment |
PINGREQ |
12 |
Client to Server |
PING request |
PINGRESP |
13 |
Server to Client |
PING response |
DISCONNECT |
14 |
Client to Server or Server to Client |
Disconnect notification |
AUTH |
15 |
Client to Server or Server to Client |
Authentication exchange |
Solace Implementation Note
Solace does not support the AUTH packet.
Solace does not support the DISCONNECT packet in the direction "Server to Client".
2.1.3 Flags
The remaining bits [3-0] of byte 1 in the Fixed Header contain flags specific to each MQTT Control Packet type as shown below.Where a flag bit is marked as “Reserved”, it is reserved for future use and MUST be set to the value listed[MQTT-2.1.3-1]. If invalid flags are received it is a Malformed Packet. Refer to section 4.13 for details about handling errors.
MQTT Control Packet |
Fixed Header flags |
Bit 3 |
Bit 2 |
Bit 1 |
Bit 0 |
CONNECT |
Reserved |
0 |
0 |
0 |
0 |
CONNACK |
Reserved |
0 |
0 |
0 |
0 |
PUBLISH |
Used in MQTT v5.0 |
DUP |
QoS |
RETAIN |
|
PUBACK |
Reserved |
0 |
0 |
0 |
0 |
PUBREC |
Reserved |
0 |
0 |
0 |
0 |
PUBREL |
Reserved |
0 |
0 |
1 |
0 |
PUBCOMP |
Reserved |
0 |
0 |
0 |
0 |
SUBSCRIBE |
Reserved |
0 |
0 |
1 |
0 |
SUBACK |
Reserved |
0 |
0 |
0 |
0 |
UNSUBSCRIBE |
Reserved |
0 |
0 |
1 |
0 |
UNSUBACK |
Reserved |
0 |
0 |
0 |
0 |
PINGREQ |
Reserved |
0 |
0 |
0 |
0 |
PINGRESP |
Reserved |
0 |
0 |
0 |
0 |
DISCONNECT |
Reserved |
0 |
0 |
0 |
0 |
AUTH |
Reserved |
0 |
0 |
0 |
0 |
DUP = Duplicate delivery of a PUBLISH packet
QoS = PUBLISH Quality of Service
RETAIN = PUBLISH retained message flag
Refer to section 3.3.1 for a description of the DUP, QoS, and RETAIN flags in the PUBLISH packet.
2.1.4 Remaining Length
Position: starts at byte 2.
The Remaining Length is a Variable Byte Integer that represents the number of bytes remaining within the current Control Packet, including data in the Variable Header and the Payload. The Remaining Length does not include the bytes used to encode the Remaining Length. The packet size is the total number of bytes in an MQTT Control Packet, this is equal to the length of the Fixed Header plus the Remaining Length.
Solace Implementation Note
Solace has limits to the size of a message, depending on the message QoS and the type of event broker.
2.2 Variable Header
Some types of MQTT Control Packet contain a Variable Header component. It resides between the Fixed Header and the Payload. The content of the Variable Header varies depending on the packet type. The Packet Identifier field of Variable Header is common in several packet types.
2.2.1 Packet Identifier
The Variable Header component of many of the MQTT Control Packet types includes a Two Byte Integer Packet Identifier field. These MQTT Control Packets are PUBLISH (where QoS > 0), PUBACK, PUBREC, PUBREL, PUBCOMP, SUBSCRIBE, SUBACK, UNSUBSCRIBE, UNSUBACK.
MQTT Control Packets that require a Packet Identifier are shown below:
Table 2‑3 MQTT Control Packets that contain a Packet Identifier
MQTT Control Packet |
Packet Identifier field |
CONNECT |
NO |
CONNACK |
NO |
PUBLISH |
YES (If QoS > 0) |
PUBACK |
YES |
PUBREC |
YES |
PUBREL |
YES |
PUBCOMP |
YES |
SUBSCRIBE |
YES |
SUBACK |
YES |
UNSUBSCRIBE |
YES |
UNSUBACK |
YES |
PINGREQ |
NO |
PINGRESP |
NO |
DISCONNECT |
NO |
AUTH |
NO |
A PUBLISH packet MUST NOT contain a Packet Identifier if its QoS value is set to 0[MQTT-2.2.1-2].
Each time a Client sends a new SUBSCRIBE, UNSUBSCRIBE,or PUBLISH (where QoS > 0) MQTT Control Packet it MUST assign it a non-zero Packet Identifier that is currently unused[MQTT-2.2.1-3].
Each time a Server sends a new PUBLISH (with QoS > 0) MQTT Control Packet it MUST assign it a non zero Packet Identifier that is currently unused[MQTT-2.2.1-4].
The Packet Identifier becomes available for reuse after the sender has processed the corresponding acknowledgement packet, defined as follows. In the case of a QoS 1 PUBLISH, this is the corresponding PUBACK; in the case of QoS 2 PUBLISH it is PUBCOMP or a PUBREC with a Reason Code of 128 or greater. For SUBSCRIBE or UNSUBSCRIBE it is the corresponding SUBACK or UNSUBACK.
Packet Identifiers used with PUBLISH, SUBSCRIBE and UNSUBSCRIBE packets form a single, unified set of identifiers separately for the Client and the Server in a Session. A Packet Identifier cannot be used by more than one command at any time.
A PUBACK, PUBREC , PUBREL, or PUBCOMP packet MUST contain the same Packet Identifier as the PUBLISH packet that was originally sent[MQTT-2.2.1-5]. A SUBACK and UNSUBACK MUST contain the Packet Identifier that was used in the corresponding SUBSCRIBE and UNSUBSCRIBE packet respectively[MQTT-2.2.1-6].
The Client and Server assign Packet Identifiers independently of each other. As a result, Client-Server pairs can participate in concurrent message exchanges using the same Packet Identifiers.
Non-normative comment
It is possible for a Client to send a PUBLISH packet with Packet Identifier 0x1234 and then receive a different PUBLISH packet with Packet Identifier 0x1234 from its Server before it receives a PUBACK for the PUBLISH packet that it sent.
Client Server PUBLISH Packet Identifier=0x1234 ----> <---- PUBLISH Packet Identifier=0x1234 PUBACK Packet Identifier=0x1234 ----> <---- PUBACK Packet Identifier=0x1234
2.2.2 Properties
The last field in the Variable Header of the CONNECT, CONNACK, PUBLISH, PUBACK, PUBREC, PUBREL, PUBCOMP, SUBSCRIBE, SUBACK, UNSUBSCRIBE, UNSUBACK, DISCONNECT, and AUTH packet is a set of Properties. In the CONNECT packet there is also an optional set of Properties in the Will Properties field with the Payload.
The set of Properties is composed of a Property Length followed by the Properties.
2.2.2.1 Property Length
The Property Length is encoded as a Variable Byte Integer. The Property Length does not include the bytes used to encode itself, but includes the length of the Properties. If there are no properties, this MUST be indicated by including a Property Length of zero[MQTT-2.2.2-1].
2.2.2.2 Property
A Property consists of an Identifier which defines its usage and data type, followed by a value. The Identifier is encoded as a Variable Byte Integer. A Control Packet which contains an Identifier which is not valid for its packet type, or contains a value not of the specified data type, is a Malformed Packet. If received, use a CONNACK or DISCONNECT packet with Reason Code 0x81 (Malformed Packet) as described in section 4.13 Handling errors. There is no significance in the order of Properties with different Identifiers.
Table 2‑4 - Properties
Identifier |
Name (usage) |
Type |
Packet / Will Properties
|
|
Dec |
Hex |
|||
1 |
0x01 |
Payload Format Indicator |
Byte |
PUBLISH, Will Properties |
2 |
0x02 |
Message Expiry Interval |
Four Byte Integer |
PUBLISH, Will Properties |
3 |
0x03 |
Content Type |
UTF-8 Encoded String |
PUBLISH, Will Properties |
8 |
0x08 |
Response Topic |
UTF-8 Encoded String |
PUBLISH, Will Properties |
9 |
0x09 |
Correlation Data |
Binary Data |
PUBLISH, Will Properties |
11 |
0x0B |
Subscription Identifier |
Variable Byte Integer |
PUBLISH, SUBSCRIBE |
17 |
0x11 |
Session Expiry Interval |
Four Byte Integer |
CONNECT, CONNACK, DISCONNECT |
18 |
0x12 |
Assigned Client Identifier |
UTF-8 Encoded String |
CONNACK |
19 |
0x13 |
Server Keep Alive |
Two Byte Integer |
CONNACK |
21 |
0x15 |
Authentication Method |
UTF-8 Encoded String |
CONNECT, CONNACK, AUTH |
22 |
0x16 |
Authentication Data |
Binary Data |
CONNECT, CONNACK, AUTH |
23 |
0x17 |
Request Problem Information |
Byte |
CONNECT |
24 |
0x18 |
Will Delay Interval |
Four Byte Integer |
Will Properties |
25 |
0x19 |
Request Response Information |
Byte |
CONNECT |
26 |
0x1A |
Response Information |
UTF-8 Encoded String |
CONNACK |
28 |
0x1C |
Server Reference |
UTF-8 Encoded String |
CONNACK, DISCONNECT |
31 |
0x1F |
Reason String |
UTF-8 Encoded String |
CONNACK, PUBACK, PUBREC, PUBREL, PUBCOMP, SUBACK, UNSUBACK, DISCONNECT, AUTH |
33 |
0x21 |
Receive Maximum |
Two Byte Integer |
CONNECT, CONNACK |
34 |
0x22 |
Topic Alias Maximum |
Two Byte Integer |
CONNECT, CONNACK |
35 |
0x23 |
Topic Alias |
Two Byte Integer |
PUBLISH |
36 |
0x24 |
Maximum QoS |
Byte |
CONNACK |
37 |
0x25 |
Retain Available |
Byte |
CONNACK |
38 |
0x26 |
User Property |
UTF-8 String Pair |
CONNECT, CONNACK, PUBLISH, Will Properties, PUBACK, PUBREC, PUBREL, PUBCOMP, SUBSCRIBE, SUBACK, UNSUBSCRIBE, UNSUBACK, DISCONNECT, AUTH |
39 |
0x27 |
Maximum Packet Size |
Four Byte Integer |
CONNECT, CONNACK |
40 |
0x28 |
Wildcard Subscription Available |
Byte |
CONNACK |
41 |
0x29 |
Subscription Identifier Available |
Byte |
CONNACK |
42 |
0x2A |
Shared Subscription Available |
Byte |
CONNACK |
Non-normative comment
Although the Property Identifier is defined as a Variable Byte Integer, in this version of the specification all of the Property Identifiers are one byte long.
2.3 Payload
Some MQTT Control Packets contain a Payload as the final part of the packet. In the PUBLISH packet this is the Application Message
Table 2‑5 - MQTT Control Packets that contain a Payload
MQTT Control Packet |
Payload |
CONNECT |
Required |
CONNACK |
None |
PUBLISH |
Optional |
PUBACK |
None |
PUBREC |
None |
PUBREL |
None |
PUBCOMP |
None |
SUBSCRIBE |
Required |
SUBACK |
Required |
UNSUBSCRIBE |
Required |
UNSUBACK |
Required |
PINGREQ |
None |
PINGRESP |
None |
DISCONNECT |
None |
AUTH |
None |
2.4 Reason Code
A Reason Code is a one byte unsigned value that indicates the result of an operation. Reason Codes less than 0x80 indicate successful completion of an operation. The normal Reason Code for success is 0. Reason Code values of 0x80 or greater indicate failure.
The CONNACK, PUBACK, PUBREC, PUBREL, PUBCOMP, DISCONNECT and AUTH Control Packets have a single Reason Code as part of the Variable Header. The SUBACK and UNSUBACK packets contain a list of one or more Reason Codes in the Payload.
The Reason Codes share a common set of values as shown below.
Reason Code |
Name |
Packets
|
|
Decimal |
Hex |
||
0 |
0x00 |
Success |
CONNACK, PUBACK, PUBREC, PUBREL, PUBCOMP, UNSUBACK, AUTH |
0 |
0x00 |
Normal disconnection |
DISCONNECT |
0 |
0x00 |
Granted QoS 0 |
SUBACK |
1 |
0x01 |
Granted QoS 1 |
SUBACK |
2 |
0x02 |
Granted QoS 2 |
SUBACK |
4 |
0x04 |
Disconnect with Will Message |
DISCONNECT |
16 |
0x10 |
No matching subscribers |
PUBACK, PUBREC |
17 |
0x11 |
No subscription existed |
UNSUBACK |
24 |
0x18 |
Continue authentication |
AUTH |
25 |
0x19 |
Re-authenticate |
AUTH |
128 |
0x80 |
Unspecified error |
CONNACK, PUBACK, PUBREC, SUBACK, UNSUBACK, DISCONNECT |
129 |
0x81 |
Malformed Packet |
CONNACK, DISCONNECT |
130 |
0x82 |
Protocol Error |
CONNACK, DISCONNECT |
131 |
0x83 |
Implementation specific error |
CONNACK, PUBACK, PUBREC, SUBACK, UNSUBACK, DISCONNECT |
132 |
0x84 |
Unsupported Protocol Version |
CONNACK |
133 |
0x85 |
Client Identifier not valid |
CONNACK |
134 |
0x86 |
Bad User Name or Password |
CONNACK |
135 |
0x87 |
Not authorized |
CONNACK, PUBACK, PUBREC, SUBACK, UNSUBACK, DISCONNECT |
136 |
0x88 |
Server unavailable |
CONNACK |
137 |
0x89 |
Server busy |
CONNACK, DISCONNECT |
138 |
0x8A |
Banned |
CONNACK |
139 |
0x8B |
Server shutting down |
DISCONNECT |
140 |
0x8C |
Bad authentication method |
CONNACK, DISCONNECT |
141 |
0x8D |
Keep Alive timeout |
DISCONNECT |
142 |
0x8E |
Session taken over |
DISCONNECT |
143 |
0x8F |
Topic Filter invalid |
SUBACK, UNSUBACK, DISCONNECT |
144 |
0x90 |
Topic Name invalid |
CONNACK, PUBACK, PUBREC, DISCONNECT |
145 |
0x91 |
Packet Identifier in use |
PUBACK, PUBREC, SUBACK, UNSUBACK |
146 |
0x92 |
Packet Identifier not found |
PUBREL, PUBCOMP |
147 |
0x93 |
Receive Maximum exceeded |
DISCONNECT |
148 |
0x94 |
Topic Alias invalid |
DISCONNECT |
149 |
0x95 |
Packet too large |
CONNACK, DISCONNECT |
150 |
0x96 |
Message rate too high |
DISCONNECT |
151 |
0x97 |
Quota exceeded |
CONNACK, PUBACK, PUBREC, SUBACK, DISCONNECT |
152 |
0x98 |
Administrative action |
DISCONNECT |
153 |
0x99 |
Payload format invalid |
CONNACK, PUBACK, PUBREC, DISCONNECT |
154 |
0x9A |
Retain not supported |
CONNACK, DISCONNECT |
155 |
0x9B |
QoS not supported |
CONNACK, DISCONNECT |
156 |
0x9C |
Use another server |
CONNACK, DISCONNECT |
157 |
0x9D |
Server moved |
CONNACK, DISCONNECT |
158 |
0x9E |
Shared Subscriptions not supported |
SUBACK, DISCONNECT |
159 |
0x9F |
Connection rate exceeded |
CONNACK, DISCONNECT |
160 |
0xA0 |
Maximum connect time |
DISCONNECT |
161 |
0xA1 |
Subscription Identifiers not supported |
SUBACK, DISCONNECT |
162 |
0xA2 |
Wildcard Subscriptions not supported |
SUBACK, DISCONNECT |
Non-normative comment
For Reason Code 0x91 (Packet identifier in use), the response to this is either to try to fix the state, or to reset the Session state by connecting using Clean Start set to 1, or to decide if the Client or Server implementations are defective.