Keep-Alive Troubleshooting (Clients Disconnected with Reason Code 141 - idle for too long)
What is Code 141, ‘Idle for Too Long’?
This reason code indicates that a client was disconnected for being idle for too long. This means that a packet has not been received from the client by the broker for 1.5x the client’s configured keep-alive setting.
How keep-alive works in MQTT
Our blog article here provides a deeper dive into the precise functions of this keep-alive mechanism : https://www.hivemq.com/blog/mqtt-essentials-part-10-alive-client-take-over/.
The keep-alive interval is a time period (recorded in seconds) that the client specifies during the initial submission of the CONNECT packet. It serves as a heartbeat mechanism to ensure the connection remains active. If the broker does not receive any packets (such as PINGREQ, PUBLISH, SUBSCRIBE, etc.) from the client within this interval, it considers the connection lost and disconnects the client. More details on this behavior can be found within the OASIS MQTT specification here : https://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#:~:text=3.1.2%2D22%5D.-,3.1.2.10%20Keep%20Alive,-Figure%203.5%20Keep
For many clients, to prevent idle timeouts during periods where PUBLISH or SUBSCRIBE messages are not being sent, they are configured to use PINGREQ messages before the keep-alive interval is exceeded by 1.5x. When a PINGREQ message is sent from a client to a broker, the broker must respond with a PINGRESP message to indicate to the client that the connection remains active. From the perspective of the broker, the reception of the PINGREQ message constitutes a received packet from the client, and the expiry timer is reset.
For example, if a client sets a keep-alive interval of 60 seconds, the broker expects to receive at least one packet every 60 seconds. If 90 seconds (1.5 times the Keep Alive interval) pass without any packet, the broker will disconnect the client with return code 141.
Logs Identifying This Behavior
This reason code, identifying an idle disconnect, is typically located in three easily identifiable locations.
Client Logs
Most client implementations will log the reason code provided when a disconnect is completed. In this case, the disconnect reason code is
141, or ‘Idle for Too Long’.
Client disconnect events will be recorded within the HiveMQ
event.logby default, which is located within the HiveMQ install directory atHiveMQ/log/event.log.
Here is a sample :Client ID: test_client, IP: 192.168.0.1 was disconnected. reason: Client was idle for too long.
When a trace recording is performed for a client, if the
DISCONNECTpacket is selected to be recorded, idle timeout disconnects will be recorded within the produced trace, and will indicate the reason code as well.
Here is a sample :2025-04-30 19:28:43,765 - [testClient] - Sent DISCONNECT message (reason code: 141, reason string: The client was idle for too long without sending an MQTT control packet.)
Recommendations / Steps to Resolve
As this behavior is the result of a client not sending a packet within 1.5x the configured keep-alive duration, there are a few routes to take to mitigate this behavior.
Review Client Activity
Ensure that
PINGREQfunctionality is configured and enabled for the client, or thatkeep-alivehandling is enabled, if thePINGREQ/PINGRESPfunctionality is handled as a component of the connection. Many clients handle this by default, but is worth validating, especially for custom implementations of client libraries.
Adjust Keep Alive Interval
If your client has periods of inactivity longer than the current
keep-aliveinterval, consider increasing it to accommodate these periods.For example, if you have a
keep-alivevalue of 60 seconds, but there are periods of time in which the client may be unavailable for longer than 90 seconds, consider increasing this value to support this scenario.
Monitor Network Stability
Check for any network issues that might be causing packet loss or delays.
Review any unexpected network disconnects for clients experiencing this error that may point towards an underlying issue.
If Using MQTT 5 Clients, ensure that the Server
Maximum Keep Alivevalue is not unexpectedly overriding the client provided values.Starting with MQTT 5, brokers have the capability to override the provided client
keep alivevalue in some scenarios.For more details on this configuration option, check out our documentation page here : https://docs.hivemq.com/hivemq-edge/mqtt-specific-configuration.html#max-keep-alive .