Queue overflow: PUBACK rc=0x00 sent for messages that are then silently dropped
I have a question regarding the interpretation of the MQTT specification.
When a client publishes QoS 1 messages and the broker's outbound queue (max_queued_messages) is full, Mosquitto immediately sends PUBACK rc=0x00 (Success) for every message — including messages it subsequently discards. The publisher has no way to detect that overflow messages were lost. In case of a bridge configuration, that means that no subscriber on the upstream broker will receive the dropped messages.
The mosquitto.conf man page documents this as intentional:
"Once this limit has been reached, subsequent messages will be silently dropped."
According to my research, EMQX and HiveMQ exhibit the same behavior, so this appears to be the de facto industry interpretation. I am raising this as a request for an opt-in alternative and, if appropriate, a prompt for a spec clarification.
Steps to reproduce
- Configure Mosquitto as a bridge to a remote broker with
max_queued_messages 3. - Have a subscriber connected on the remote broker, subscribed to the bridged topic.
- Disconnect the upstream broker (simulate outage).
- Publish 5 QoS 1 messages to the bridge.
- Reconnect the upstream broker.
Observed: All 5 PUBACK packets arrive at the publisher with rc=0x00. Only 3 messages are delivered to the cloud subscriber. The 2 overflow messages are permanently lost with no signal to the publisher.
Spec context and open question
MQTT 5.0 §4.3.2 [MQTT-4.3.2-4] requires the QoS 1 receiver to send PUBACK "having accepted ownership of the Application Message", and §3.4.2.1 Table 3-4 defines:
| Code | Meaning |
|---|---|
0x00 Success |
"The message is accepted. Publication of the QoS 1 message proceeds." |
0x97 Quota exceeded |
"An implementation or administrative imposed limit has been exceeded." |
There are (at least) two ways to read rc=0x00 here:
- Strict: "Ownership accepted" implies a delivery commitment; sending
rc=0x00for a message that is then discarded violates this. - Loose:
rc=0x00confirms receipt at the broker only; what the broker does with the message internally (forward to bridge, queue for subscriber, etc.) is outside the QoS 1 protocol contract.
Given that Mosquitto, EMQX, and HiveMQ all implement the loose interpretation, that appears to be the community consensus.
Questions for the Mosquitto project:
- Can you confirm that the loose interpretation above is your intended reading of §4.3.2?
- Would the project consider an opt-in configuration option (e.g.
queue_full_puback_reason_code 0x97) that sendsPUBACK rc=0x97instead of silently dropping, for deployments that need explicit back-pressure signalling? - If this is a wider ambiguity, would it be worth raising as a clarification request for MQTT 5.1?
Source: eclipse-mosquitto/mosquitto