MQTT Maximum Packet Size: Reject Oversized Payloads Before Resource Exhaustion
Compare the peer’s limit with the complete encoded MQTT control packet, not just the application payload. Topic bytes, packet identifiers, properties and variable-length length fields all consume the budget. Validate incoming declared packet size before allocating its body, while retaining a separate local memory limit.
This guide uses the OASIS MQTT 5.0 Standard, 7 March 2019. The executed Python fixture encoded small synthetic QoS 1 PUBLISH packets and checked length boundaries. It did not run an MQTT client, broker, transport parser or memory-exhaustion attack. Target-library behavior remains to be qualified.
Keep the two limits directional
The Maximum Packet Size in CONNECT limits packets the client accepts from the server. The CONNACK property limits packets the server accepts from the client. Sections 3.1.2.11.4 and 3.2.2.3.6 define these properties for total control-packet bytes. A zero value is invalid; omission leaves the protocol’s own encoding limits rather than promising unlimited local storage.
Record both received and advertised values with the connection generation. For an outgoing packet, apply the relevant peer limit and the sender’s own encoding/storage limits. For incoming packets, enforce the advertised receive limit and the actual local buffer policy. Do not collapse these into one global minimum that obscures which direction is failing.

Build a byte ledger for PUBLISH
For a full-topic PUBLISH, let T be the UTF-8 topic length in bytes, P the encoded property bytes and L the payload bytes. Let V(x) be the number of bytes used by MQTT’s Variable Byte Integer encoding. The Remaining Length R is:
R = 2 + T + packet_identifier_bytes + V(P) + P + L
complete_packet_bytes = 1 + V(R) + R
The packet-identifier term is zero for QoS 0 and two for QoS 1 or 2. Even an empty property list has its property-length encoding. Count UTF-8 bytes, not displayed characters. Include every configured property and the encoding of its own value; application metadata can consume space before the payload begins.
Sections 1.5.5, 2.1.4 and 3.3 define the length and PUBLISH structure. The formula is an engineering decomposition of those fields, not a new protocol limit. Use checked arithmetic in firmware and compare against the actual encoded result in regression tests.
Test the discontinuity at Remaining Length 128
The executed fixture used ASCII topic “lab/x,” QoS 1, packet identifier one and no properties. Its variable header occupied ten bytes. With a 117-byte payload, R was 127 and the full packet occupied 129 bytes. With a 118-byte payload, R became 128 and the full packet occupied 131 bytes.
Thus a hypothetical peer limit of 130 accepts the first packet size and rejects the second: one more payload byte required two more packet bytes because the Remaining Length encoding grew. These are generated-byte counts from an original local encoder, not measured broker acceptance results.
The fixture also checked Variable Byte Integer widths around 127/128, 16383/16384 and later encoding boundaries. Similar expansion can occur in the property-length field. Include both kinds of boundary in a real encoder’s size tests rather than assuming a constant header allowance.
Account for connection-dependent encoding
A topic alias can shorten later packets, but the first mapping on a new connection needs the appropriate full topic and alias property. Budget that installation packet separately. A design that fits only after alias compression can fail immediately after reconnect, when the old mapping is no longer available.
Broker-to-subscriber packets also need their own ledger. Subscription Identifiers or other applicable properties can differ from the publisher’s outgoing packet. A packet that fit the broker’s receive limit is not automatically small enough for every subscriber’s receive limit.
The standard’s client-advertised limit requires the server to discard an application message that is too large to send to that client and behave as though that sending step completed. A successful publisher-side exchange therefore does not prove that a constrained subscriber received the message. Preserve per-destination diagnostics where the implementation exposes them.
Reject declared oversize before allocating the body
On reception, parse the fixed header and bounded Remaining Length encoding first. Once the complete declared size is known, compare it with the permitted limit before reserving the whole body. Keep incomplete-header state bounded and handle malformed length encodings through the selected parser’s documented error path.
For a validly encoded packet exceeding the advertised maximum, MQTT 5.0 specifies Packet too large reason 0x95 within its error-handling rules. Do not attempt to buffer the entire oversized body merely to produce that diagnosis. The actual library may expose a connection error rather than a fully decoded packet; test its API behavior.
Maximum Packet Size is not a complete resource-exhaustion defense. Many permitted small packets can still fill application queues or consume processing time. This guide’s release gate concerns one packet’s byte extent; queue admission and workload bounds remain separate controls.
Qualification checklist
- Capture the actual CONNECT and CONNACK limits and retain them by direction.
- Compare the size estimator with bytes emitted by the real encoder for all enabled properties and QoS levels.
- Test exactly at the accepted limit and one encoded byte beyond it, including length-field transitions.
- Repeat after reconnect, with alias installation and changed peer limits.
- Test a large publisher message against a smaller subscriber limit and inspect destination-specific loss evidence.
- Feed declared oversize and malformed lengths into an isolated parser harness and check allocation bounds before application dispatch.
Accept the implementation when its byte ledger, encoder output and rejection behavior agree. A payload-size constant is sufficient only if the surrounding packet fields are fixed and their worst-case encodings have actually been included.