MQTT CONNACK:数据包标识符耗尽(原因代码 0x93)
MQTT CONNACK: Packet identifier exhausted (reason code 0x93)
ID: communication/mqtt-packet-identifier-exhausted
版本兼容性
| 版本 | 状态 | 引入 | 弃用 | 备注 |
|---|---|---|---|---|
| MQTT 3.1.1 | active | — | — | — |
| MQTT 5.0 | active | — | — | — |
| Mosquitto 2.0.15 | active | — | — | — |
| EMQX 5.0.0 | active | — | — | — |
| HiveMQ 2023.1 | active | — | — | — |
根因分析
MQTT 代理耗尽可用数据包标识符(0-65535),因为太多未确认的 PUBLISH/QoS>0 或 SUBSCRIBE 消息正在传输中,通常是由于消费者缓慢或网络拥塞。
English
MQTT broker runs out of available packet identifiers (0-65535) because too many unacknowledged PUBLISH/QoS>0 or SUBSCRIBE messages are in flight, typically due to slow consumers or network congestion.
官方文档
https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901257解决方案
-
Increase the packet identifier pool size on the broker (if configurable): for Mosquitto, set 'max_inflight_messages' to a higher value (e.g., 65535) to allow more concurrent in-flight messages.
-
Implement flow control on the client: limit the number of unacknowledged PUBLISH messages by using a sliding window (e.g., max 10 in-flight per topic) and wait for PUBACK before sending the next.
-
Upgrade to MQTT 5.0 and use the 'Topic Alias' and 'Receive Maximum' properties to reduce identifier consumption by allowing the broker to limit client send rate.
无效尝试
常见但无效的做法:
-
70% 失败
Increasing the MQTT client's keepalive interval only delays disconnection; the packet identifier pool remains exhausted.
-
75% 失败
Setting QoS=0 (fire-and-forget) reduces reliability and may cause message loss; it also doesn't fix the root cause if the broker's identifier pool is globally exhausted across all clients.
-
60% 失败
Restarting the broker clears the pool temporarily but the same pattern will recur if the underlying slow-consumer issue isn't addressed.