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.

 

Table 2‑2 Flag Bits

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.

 

Table 2‑6 - Reason Codes

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.