From 216fa94860b5eabc263881f5d2e797e7f5ef06ff Mon Sep 17 00:00:00 2001 From: Thales Macedo Garitezi <16166434+thalesmg@users.noreply.github.com> Date: Thu, 7 Aug 2025 15:52:25 -0300 Subject: [PATCH 1/5] feat: list common disconnect reasons --- en_US/admin/cli.md | 36 ++++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/en_US/admin/cli.md b/en_US/admin/cli.md index b5478b40f..e3bba350b 100644 --- a/en_US/admin/cli.md +++ b/en_US/admin/cli.md @@ -102,9 +102,9 @@ Loaded 'Mod' module on []: ok ## conf cluster_sync -This command is mostly for troubleshooting when there is something wrong with cluster-calls used to sync configuration changes between the nodes in the cluster. +This command is mostly for troubleshooting when there is something wrong with cluster-calls used to sync configuration changes between the nodes in the cluster. -::: tip +::: tip In EMQX 5.0.x, this command was named `cluster_call`. This old command is still available in EMQX 5.1 but it is not displayed in the help information. @@ -704,7 +704,7 @@ This command is like the `trace` command, but applies on all nodes in the cluste ## traces -This command is similar to the `trace` command, but it starts or stops a tracer across all nodes in the cluster. +This command is similar to the `trace` command, but it starts or stops a tracer across all nodes in the cluster. | Command | Description | | ------------------------------------------------------- | --------------------------------- | @@ -787,6 +787,7 @@ tcp:default running : true current_conn : 12 max_conns : 5000000 + shutdown_count : [{takenover,2},{discarded,1}] ws:default listen_on : 0.0.0.0:8083 acceptors : 16 @@ -803,6 +804,33 @@ wss:default max_conns : 5000000 ``` +#### Common shutdown reasons + +| Reason | Description | +|-------------------------------|-------------------------------------------------------------------------------------------------------| +| `banned` | The client is blacklisted due to ACL violations, rate limiting, or IP restrictions. | +| `closed` | The connection was closed either by the server or the client. | +| `discarded` | A client with the same clientid connected with `clean_start = true` while the old session was alive. | +| `takenover` | A client with the same clientid connected with `clean_start = false` while the old session was alive. | +| `einval` | Invalid argument or socket error, typically indicating a network or client SDK issue. | +| `frame_too_large` | The MQTT packet exceeds the maximum allowed frame size. | +| `idle_timeout` | The connection was idle beyond the configured timeout period. | +| `invalid_proto_name` | The protocol name in the `CONNECT` packet is invalid or not `"MQTT"`. | +| `invalid_topic` | The client used an invalid topic (e.g., containing illegal characters or forbidden by the broker). | +| `keepalive_timeout` | The client failed to send any packets within the keepalive interval. | +| `malformed_packet` | The MQTT packet is corrupted or does not conform to the MQTT specification. | +| `not_authorized` | The client attempted an unauthorized action, rejected by ACL. | +| `ssl_closed` | The SSL/TLS connection was closed by the peer. | +| `ssl_error` | A SSL/TLS handshake or data transmission error occurred. | +| `ssl_upgrade_timeout` | Timeout during SSL/TLS upgrade or handshake. | +| `unexpected_packet` | The client sent a packet that was unexpected in the current connection state. | +| `zero_remaining_len` | The packet has a zero remaining length field, which is invalid in most contexts. | +| `bad_username_or_password` | The client's credentials failed authentication. | +| `client_identifier_not_valid` | The client ID is invalid or disallowed. | +| `protocol_error` | A generic MQTT protocol violation. | +| `tcp_closed` | The TCP connection was closed by the client or network layer. | +| `timeout` | A general timeout occurred (e.g., during authentication, SSL handshake, etc.). | + ### listeners stop \ ```bash @@ -832,7 +860,7 @@ Restarted tcp:default listener successfully. Restarting a listener causes all the connected clients to disconnect. ::: -### listeners enable \ +### listeners enable \ ```bash $ emqx ctl listeners enable tcp:default true From afa44c47e3a7dc8356f162672d82c98dd82850a0 Mon Sep 17 00:00:00 2001 From: Thales Macedo Garitezi <16166434+thalesmg@users.noreply.github.com> Date: Thu, 14 Aug 2025 09:25:07 -0300 Subject: [PATCH 2/5] chore: improve descriptions Co-authored-by: zmstone --- en_US/admin/cli.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/en_US/admin/cli.md b/en_US/admin/cli.md index e3bba350b..ffac4c02e 100644 --- a/en_US/admin/cli.md +++ b/en_US/admin/cli.md @@ -812,9 +812,9 @@ wss:default | `closed` | The connection was closed either by the server or the client. | | `discarded` | A client with the same clientid connected with `clean_start = true` while the old session was alive. | | `takenover` | A client with the same clientid connected with `clean_start = false` while the old session was alive. | -| `einval` | Invalid argument or socket error, typically indicating a network or client SDK issue. | +| `einval` | Invalid argument or socket error, happens when EMQX tries to write data to a socket which is closed already by the system (a race condition between socket state change notification and data write). | | `frame_too_large` | The MQTT packet exceeds the maximum allowed frame size. | -| `idle_timeout` | The connection was idle beyond the configured timeout period. | +| `idle_timeout` | The `CONNECT` packet is not received for too long after the configured timeout after connection is established. | | `invalid_proto_name` | The protocol name in the `CONNECT` packet is invalid or not `"MQTT"`. | | `invalid_topic` | The client used an invalid topic (e.g., containing illegal characters or forbidden by the broker). | | `keepalive_timeout` | The client failed to send any packets within the keepalive interval. | @@ -822,14 +822,14 @@ wss:default | `not_authorized` | The client attempted an unauthorized action, rejected by ACL. | | `ssl_closed` | The SSL/TLS connection was closed by the peer. | | `ssl_error` | A SSL/TLS handshake or data transmission error occurred. | -| `ssl_upgrade_timeout` | Timeout during SSL/TLS upgrade or handshake. | +| `ssl_upgrade_timeout` | Timeout during SSL/TLS handshake. | | `unexpected_packet` | The client sent a packet that was unexpected in the current connection state. | | `zero_remaining_len` | The packet has a zero remaining length field, which is invalid in most contexts. | | `bad_username_or_password` | The client's credentials failed authentication. | -| `client_identifier_not_valid` | The client ID is invalid or disallowed. | +| `client_identifier_not_valid` | The client ID is being registered by another connection. | | `protocol_error` | A generic MQTT protocol violation. | | `tcp_closed` | The TCP connection was closed by the client or network layer. | -| `timeout` | A general timeout occurred (e.g., during authentication, SSL handshake, etc.). | +| `timeout` | A general timeout occurred (e.g., during authentication, etc.). | ### listeners stop \ From 812a986d31a6b1fc2b428a9d8b6633864a37935e Mon Sep 17 00:00:00 2001 From: Meggielqk <126552073+Meggielqk@users.noreply.github.com> Date: Thu, 21 Aug 2025 11:10:17 +0800 Subject: [PATCH 3/5] Add zh translation --- en_US/admin/cli.md | 65 +++++++++++++++++++++++++++------------------- zh_CN/admin/cli.md | 41 +++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+), 26 deletions(-) diff --git a/en_US/admin/cli.md b/en_US/admin/cli.md index ffac4c02e..f56cc97b1 100644 --- a/en_US/admin/cli.md +++ b/en_US/admin/cli.md @@ -804,32 +804,45 @@ wss:default max_conns : 5000000 ``` -#### Common shutdown reasons - -| Reason | Description | -|-------------------------------|-------------------------------------------------------------------------------------------------------| -| `banned` | The client is blacklisted due to ACL violations, rate limiting, or IP restrictions. | -| `closed` | The connection was closed either by the server or the client. | -| `discarded` | A client with the same clientid connected with `clean_start = true` while the old session was alive. | -| `takenover` | A client with the same clientid connected with `clean_start = false` while the old session was alive. | -| `einval` | Invalid argument or socket error, happens when EMQX tries to write data to a socket which is closed already by the system (a race condition between socket state change notification and data write). | -| `frame_too_large` | The MQTT packet exceeds the maximum allowed frame size. | -| `idle_timeout` | The `CONNECT` packet is not received for too long after the configured timeout after connection is established. | -| `invalid_proto_name` | The protocol name in the `CONNECT` packet is invalid or not `"MQTT"`. | -| `invalid_topic` | The client used an invalid topic (e.g., containing illegal characters or forbidden by the broker). | -| `keepalive_timeout` | The client failed to send any packets within the keepalive interval. | -| `malformed_packet` | The MQTT packet is corrupted or does not conform to the MQTT specification. | -| `not_authorized` | The client attempted an unauthorized action, rejected by ACL. | -| `ssl_closed` | The SSL/TLS connection was closed by the peer. | -| `ssl_error` | A SSL/TLS handshake or data transmission error occurred. | -| `ssl_upgrade_timeout` | Timeout during SSL/TLS handshake. | -| `unexpected_packet` | The client sent a packet that was unexpected in the current connection state. | -| `zero_remaining_len` | The packet has a zero remaining length field, which is invalid in most contexts. | -| `bad_username_or_password` | The client's credentials failed authentication. | -| `client_identifier_not_valid` | The client ID is being registered by another connection. | -| `protocol_error` | A generic MQTT protocol violation. | -| `tcp_closed` | The TCP connection was closed by the client or network layer. | -| `timeout` | A general timeout occurred (e.g., during authentication, etc.). | +#### Common Shutdown Reasons + +For TCP listeners, EMQX reports a `shutdown_count` field, which records how many client disconnections occurred, grouped by reason. This can help identify why clients are getting disconnected from the TCP listener. + +```bash +shutdown_count : [{takenover,2},{discarded,1}] +``` + +In the example above: + +- 2 clients were disconnected because a new session took over the same `clientid`. +- 1 client was discarded because a new clean session replaced it. + +Below is a list of common shutdown reasons that may appear in this field. + +| Reason | Description | +| ----------------------------- | ------------------------------------------------------------ | +| `banned` | The client is blacklisted due to ACL violations, rate limiting, or IP restrictions. | +| `closed` | The connection was closed either by the server or the client. | +| `discarded` | A new client with the same `clientid` and `clean_start = true` connected while the previous session was still active. | +| `takenover` | A new client with the same `clientid` and `clean_start = false` connected while the previous session was still active. | +| `einval` | An invalid argument or socket error occurred, often caused by attempting to write to a socket that has already been closed (a race condition between socket state change notification and data write). | +| `frame_too_large` | The MQTT packet exceeds the maximum allowed frame size. | +| `idle_timeout` | No `CONNECT` packet was received within the allowed time after the TCP/SSL connection was established. | +| `invalid_proto_name` | The protocol name in the `CONNECT` packet is invalid or not `"MQTT"`. | +| `invalid_topic` | The client used an invalid topic (e.g., containing illegal characters or forbidden by the broker). | +| `keepalive_timeout` | The client failed to send any packets within the keepalive interval. | +| `malformed_packet` | The MQTT packet is corrupted or does not conform to the MQTT specification. | +| `not_authorized` | The client attempted an unauthorized action, rejected by ACL. | +| `ssl_closed` | The SSL/TLS connection was closed by the peer. | +| `ssl_error` | An error occurred during the SSL/TLS handshake or data transmission. | +| `ssl_upgrade_timeout` | The SSL/TLS handshake did not complete within the allowed time. | +| `unexpected_packet` | The client sent a packet that was unexpected in the current connection state. | +| `zero_remaining_len` | The packet has a zero remaining length field, which is invalid in most contexts. | +| `bad_username_or_password` | Authentication failed due to incorrect username or password. | +| `client_identifier_not_valid` | The provided `clientid` is invalid or is already in use by another connection. | +| `protocol_error` | A generic MQTT protocol violation occurred. | +| `tcp_closed` | The TCP connection was closed by the client or due to a network issue. | +| `timeout` | A general timeout occurred (e.g., during authentication, etc.). | ### listeners stop \ diff --git a/zh_CN/admin/cli.md b/zh_CN/admin/cli.md index 07af723ad..1b8afe729 100644 --- a/zh_CN/admin/cli.md +++ b/zh_CN/admin/cli.md @@ -782,6 +782,7 @@ tcp:default running : true current_conn : 12 max_conns : 5000000 + shutdown_count : [{takenover,2},{discarded,1}] ws:default listen_on : 0.0.0.0:8083 acceptors : 16 @@ -798,6 +799,46 @@ wss:default max_conns : 5000000 ``` +#### 常见连接关闭原因 + +对于 TCP 监听器,EMQX 会报告一个 `shutdown_count` 字段,用于统计客户端断开连接的次数,并按原因分类。该字段有助于分析客户端为何被断开连接。 + +``` +shutdown_count : [{takenover,2},{discarded,1}] +``` + +上述示例中: + +- 有 2 个客户端因为新的会话接管了相同的 `clientid` 而被断开连接(`takenover`)。 +- 有 1 个客户端因为被新的 clean session 替换而被丢弃(`discarded`)。 + +以下是 `shutdown_count` 字段中可能出现的一些常见断开原因: + +| 原因 | 描述 | +| ----------------------------- | ------------------------------------------------------------ | +| `banned` | 客户端因违反 ACL 规则、触发限流或 IP 被限制而被拉入黑名单并断开连接。 | +| `closed` | 连接被服务器或客户端主动关闭。 | +| `discarded` | 新客户端使用相同的 `clientid` 且设置了 `clean_start = true`,在旧会话仍然活跃的情况下连接,导致旧会话被丢弃。 | +| `takenover` | 新客户端使用相同的 `clientid` 且设置了 `clean_start = false`,在旧会话仍然活跃的情况下连接,导致旧会话被接管。 | +| `einval` | 出现无效参数或 socket 错误,通常是因为尝试向已被系统关闭的 socket 写入数据(可能是 socket 状态变更通知与数据写入之间的竞争条件所致)。 | +| `frame_too_large` | 收到的 MQTT 报文超过了允许的最大帧大小。 | +| `idle_timeout` | TCP/SSL 连接建立后,在配置的超时时间内未收到 `CONNECT` 报文。 | +| `invalid_proto_name` | `CONNECT` 报文中的协议名称无效或不是 `"MQTT"`。 | +| `invalid_topic` | 客户端使用了无效或被禁止的主题(如包含非法字符或被 Broker 限制)。 | +| `keepalive_timeout` | 客户端在 Keep Alive 时间间隔内未发送任何报文。 | +| `malformed_packet` | MQTT 报文损坏或不符合 MQTT 协议规范。 | +| `not_authorized` | 客户端尝试执行未被授权的操作,被 ACL 拒绝。 | +| `ssl_closed` | SSL/TLS 连接被对端关闭。 | +| `ssl_error` | SSL/TLS 握手或数据传输过程中发生错误。 | +| `ssl_upgrade_timeout` | SSL/TLS 握手未在允许时间内完成。 | +| `unexpected_packet` | 客户端在当前连接状态下发送了不应出现的报文。 | +| `zero_remaining_len` | MQTT 报文的剩余长度字段为 0,在大多数场景下是非法的。 | +| `bad_username_or_password` | 客户端身份认证失败,用户名或密码错误。 | +| `client_identifier_not_valid` | 提供的 `clientid` 无效,或已被其他连接使用。 | +| `protocol_error` | 出现通用的 MQTT 协议错误。 | +| `tcp_closed` | TCP 连接被客户端或网络层关闭。 | +| `timeout` | 发生通用超时错误(如在认证或握手过程中)。 | + ### listeners stop \ ```bash From 81edd5ebb3f9df9f25b96bf4c22ed332ab86416f Mon Sep 17 00:00:00 2001 From: Meggielqk <126552073+Meggielqk@users.noreply.github.com> Date: Fri, 22 Aug 2025 13:28:20 +0800 Subject: [PATCH 4/5] Update en_US/admin/cli.md Co-authored-by: zmstone --- en_US/admin/cli.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/en_US/admin/cli.md b/en_US/admin/cli.md index f56cc97b1..ac149d4fd 100644 --- a/en_US/admin/cli.md +++ b/en_US/admin/cli.md @@ -839,7 +839,7 @@ Below is a list of common shutdown reasons that may appear in this field. | `unexpected_packet` | The client sent a packet that was unexpected in the current connection state. | | `zero_remaining_len` | The packet has a zero remaining length field, which is invalid in most contexts. | | `bad_username_or_password` | Authentication failed due to incorrect username or password. | -| `client_identifier_not_valid` | The provided `clientid` is invalid or is already in use by another connection. | +| `client_identifier_not_valid` | The provided `clientid` is invalid or locked by another client during login. | | `protocol_error` | A generic MQTT protocol violation occurred. | | `tcp_closed` | The TCP connection was closed by the client or due to a network issue. | | `timeout` | A general timeout occurred (e.g., during authentication, etc.). | From 0a00bfd6ff7aa04ba929cd8259c853f130eaec4c Mon Sep 17 00:00:00 2001 From: Meggielqk <126552073+Meggielqk@users.noreply.github.com> Date: Fri, 22 Aug 2025 13:28:29 +0800 Subject: [PATCH 5/5] Update zh_CN/admin/cli.md Co-authored-by: zmstone --- zh_CN/admin/cli.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zh_CN/admin/cli.md b/zh_CN/admin/cli.md index 1b8afe729..2cda1f281 100644 --- a/zh_CN/admin/cli.md +++ b/zh_CN/admin/cli.md @@ -834,7 +834,7 @@ shutdown_count : [{takenover,2},{discarded,1}] | `unexpected_packet` | 客户端在当前连接状态下发送了不应出现的报文。 | | `zero_remaining_len` | MQTT 报文的剩余长度字段为 0,在大多数场景下是非法的。 | | `bad_username_or_password` | 客户端身份认证失败,用户名或密码错误。 | -| `client_identifier_not_valid` | 提供的 `clientid` 无效,或已被其他连接使用。 | +| `client_identifier_not_valid` | 提供的 `clientid` 无效,或被另一个正在登录的客户端锁定。 | | `protocol_error` | 出现通用的 MQTT 协议错误。 | | `tcp_closed` | TCP 连接被客户端或网络层关闭。 | | `timeout` | 发生通用超时错误(如在认证或握手过程中)。 |