MQTT reason code lookup
Got a 0x87, a 135 or “Connection refused: not authorized”? Search every MQTT 5 reason code and MQTT 3.1.1 return code to see what it means and how to fix it.
- CONNACK
The server rejected the username or password.
How to fix: Double-check credentials (watch for trailing spaces and case), and confirm the user exists in the broker password file or auth backend.
Tip: per-user credentials and topic ACLs are easier to get right when you control the broker — ConnectMQ lets you manage both from a dashboard.
- CONNACKPUBACKPUBRECSUBACKUNSUBACKDISCONNECT
The client is not allowed to do this — connect, publish to that topic, or subscribe to that filter.
How to fix: Check the broker ACL for this user and topic. On CONNACK it often means anonymous access is disabled and no credentials were sent.
Tip: per-user credentials and topic ACLs are easier to get right when you control the broker — ConnectMQ lets you manage both from a dashboard.
- CONNACK
The client ID is well-formed but the server will not accept it (too long, bad characters, or empty when not allowed).
How to fix: Use a short alphanumeric client ID (max 23 characters is always safe) or let the broker assign one with an empty ID and clean start.
- DISCONNECT
Another connection with the same client ID connected, so this one was kicked off.
How to fix: Give every device and every browser tab a unique client ID. Two clients sharing an ID will disconnect each other in a loop.
- DISCONNECT
No packet was received within 1.5 × the Keep Alive interval, so the connection was closed.
How to fix: Make sure your client loop runs (PINGREQ is sent), avoid blocking the network thread, or increase the keep alive interval.
- CONNACKPUBACKPUBRECSUBACKUNSUBACKDISCONNECT
Something failed and the server does not want to (or cannot) say what.
How to fix: Check the broker logs — they usually contain the real cause. Also look at the Reason String property if one was sent.
- CONNACKPUBACKPUBRECSUBACKDISCONNECT
An implementation or administrative quota was exceeded (messages, connections, storage, …).
How to fix: Check your plan or broker quotas, reduce message volume, or ask the operator to raise the limit.
Tip: per-user credentials and topic ACLs are easier to get right when you control the broker — ConnectMQ lets you manage both from a dashboard.
- CONNACK
The client is not authorized to connect.
How to fix: Send credentials if anonymous access is disabled, and check the broker ACL for this user.
Tip: per-user credentials and topic ACLs are easier to get right when you control the broker — ConnectMQ lets you manage both from a dashboard.
How MQTT reason codes work
A reason code is a single byte the broker (or client) sends back to say how an operation went. In MQTT 5 they appear in CONNACK, PUBACK, PUBREC, PUBREL, PUBCOMP, SUBACK, UNSUBACK, DISCONNECT and AUTH. The rule is simple: values below 0x80 mean success (sometimes with extra information, like 0x10 No matching subscribers), and 0x80 and above mean failure. The same number has the same meaning in every packet where it is allowed, so 0x87 is always “Not authorized” — whether it comes back on a connect, a publish or a subscribe.
MQTT 3.1.1 is much less talkative. Only CONNACK carries a return code (0–5) and SUBACK can only say “granted QoS 0/1/2” or 0x80 Failure. A rejected QoS 0 publish is silently dropped, and many brokers simply close the TCP connection on errors, so the broker log is often your only clue. If you need precise error reporting, MQTT 5 is worth the switch.
Reading the codes your library shows you
Client libraries print codes in different ways. Paho Python shows decimal values (rc=135), MQTT.js usually shows the decimal number together with a message, and Mosquitto's command-line tools print text such as “Connection Refused: not authorised”. The search box above accepts all of them: type 135, 0x87, 87 or a phrase like keep alive. In MQTT 5 the broker may also include a Reason String property with a human-readable explanation — log it, because it is often more specific than the code itself.
The errors you will hit most often
- 0x86 / return code 4 — bad username or password. Check for typos, trailing whitespace and case. See the Mosquitto authentication guide for setting up password files.
- 0x87 / return code 5 — not authorized. The credentials may be fine but the ACL blocks the topic, or the broker refuses anonymous clients.
- 0x8E — session taken over. Two clients share a client ID. Generate unique IDs with the client ID generator.
- 0x8D — keep alive timeout. The client stopped sending packets. Read how MQTT keep alive works.
- 0x95 — packet too large. Check your message size with the packet size calculator.
Many connection problems never reach the point of a reason code — DNS failures, wrong ports and TLS handshake errors happen before MQTT starts. For those, see common MQTT connection errors and the MQTT ports reference, or reproduce the issue in the online MQTT client, which shows the CONNACK result in its log.
All MQTT 5 reason codes
Every reason code defined in section 2.4 of the OASIS MQTT 5.0 specification. Link to a code with #0x87.
| Code | Name | Packets | Meaning & fix |
|---|---|---|---|
| 0x00 dec 0 | Success | CONNACK, PUBACK, PUBREC, PUBREL, PUBCOMP, UNSUBACK, AUTH | The operation completed successfully. Fix: Nothing to fix — this is the normal result. |
| 0x00 dec 0 | Normal disconnection | DISCONNECT | The connection was closed on purpose and the Will Message is not sent. Fix: Nothing to fix. If you did not expect the disconnect, check which side sent it and why. |
| 0x00 dec 0 | Granted QoS 0 | SUBACK | The subscription was accepted with a maximum QoS of 0. Fix: If you asked for QoS 1 or 2, the broker downgraded you — check its maximum QoS setting. |
| 0x01 dec 1 | Granted QoS 1 | SUBACK | The subscription was accepted with a maximum QoS of 1. Fix: If you asked for QoS 2, the broker caps QoS at 1 — design for at-least-once delivery (idempotent handlers). |
| 0x02 dec 2 | Granted QoS 2 | SUBACK | The subscription was accepted with a maximum QoS of 2. Fix: Nothing to fix — you got exactly-once delivery as requested. |
| 0x04 dec 4 | Disconnect with Will Message | DISCONNECT | The client wants to disconnect but asks the server to publish its Will Message anyway. Fix: Nothing to fix — this is a deliberate choice by the client. |
| 0x10 dec 16 | No matching subscribers | PUBACK, PUBREC | The message was accepted, but nobody is currently subscribed to that topic. Fix: Not an error. Check the subscriber is connected and its topic filter matches the topic exactly (case-sensitive). |
| 0x11 dec 17 | No subscription existed | UNSUBACK | The client tried to unsubscribe from a topic filter it was not subscribed to. Fix: Make sure the unsubscribe filter is byte-for-byte identical to the one you subscribed with. |
| 0x18 dec 24 | Continue authentication | AUTH | Enhanced authentication is in progress and another AUTH step is needed. Fix: Your client must answer with an AUTH packet containing the next step of the authentication method. |
| 0x19 dec 25 | Re-authenticate | AUTH | The client asks to re-run enhanced authentication on an existing connection. Fix: Nothing to fix — used to refresh credentials such as expiring tokens. |
| 0x80 dec 128 | Unspecified error | CONNACK, PUBACK, PUBREC, SUBACK, UNSUBACK, DISCONNECT | Something failed and the server does not want to (or cannot) say what. Fix: Check the broker logs — they usually contain the real cause. Also look at the Reason String property if one was sent. |
| 0x81 dec 129 | Malformed Packet | CONNACK, DISCONNECT | The received packet does not follow the MQTT specification and could not be parsed. Fix: Update your client library, make sure the protocol version matches, and check that you are not speaking MQTT to a non-MQTT port (or plain TCP to a TLS port). |
| 0x82 dec 130 | Protocol Error | CONNACK, DISCONNECT | The packet parsed correctly but broke a protocol rule, e.g. a second CONNECT or a duplicate property. Fix: Usually a client library bug or custom packet code. Update the library and avoid sending packets out of order. |
| 0x83 dec 131 | Implementation specific error | CONNACK, PUBACK, PUBREC, SUBACK, UNSUBACK, DISCONNECT | The packet is valid but the server rejects it for a broker-specific reason. Fix: Read the Reason String and the broker documentation/logs — the cause depends on the broker (plugins, limits, policies). |
| 0x84 dec 132 | Unsupported Protocol Version | CONNACK | The server does not support the MQTT protocol version the client requested. Fix: Switch the client to MQTT 3.1.1 (protocol level 4) or upgrade the broker to one that supports MQTT 5. |
| 0x85 dec 133 | Client Identifier not valid | CONNACK | The client ID is well-formed but the server will not accept it (too long, bad characters, or empty when not allowed). Fix: Use a short alphanumeric client ID (max 23 characters is always safe) or let the broker assign one with an empty ID and clean start. |
| 0x86 dec 134 | Bad User Name or Password | CONNACK | The server rejected the username or password. Fix: Double-check credentials (watch for trailing spaces and case), and confirm the user exists in the broker password file or auth backend. |
| 0x87 dec 135 | Not authorized | CONNACK, PUBACK, PUBREC, SUBACK, UNSUBACK, DISCONNECT | The client is not allowed to do this — connect, publish to that topic, or subscribe to that filter. Fix: Check the broker ACL for this user and topic. On CONNACK it often means anonymous access is disabled and no credentials were sent. |
| 0x88 dec 136 | Server unavailable | CONNACK | The MQTT server is not available right now. Fix: Retry with exponential backoff. If it persists, check broker health, cluster state and maintenance windows. |
| 0x89 dec 137 | Server busy | CONNACK, DISCONNECT | The server is overloaded and refuses the operation; try again later. Fix: Back off and retry with jitter so thousands of devices do not reconnect at the same moment. |
| 0x8A dec 138 | Banned | CONNACK | This client has been banned by administrative action. Fix: Contact the broker operator. Repeated failed logins or abusive traffic are common reasons for bans. |
| 0x8B dec 139 | Server shutting down | DISCONNECT | The server is shutting down. Fix: Reconnect with backoff; use a persistent session so subscriptions and queued QoS 1/2 messages survive. |
| 0x8C dec 140 | Bad authentication method | CONNACK, DISCONNECT | The authentication method in CONNECT is not supported or does not match the one in use. Fix: Remove the Authentication Method property or set it to a method the broker supports (e.g. SCRAM-SHA-256). |
| 0x8D dec 141 | Keep Alive timeout | DISCONNECT | No packet was received within 1.5 × the Keep Alive interval, so the connection was closed. Fix: Make sure your client loop runs (PINGREQ is sent), avoid blocking the network thread, or increase the keep alive interval. |
| 0x8E dec 142 | Session taken over | DISCONNECT | Another connection with the same client ID connected, so this one was kicked off. Fix: Give every device and every browser tab a unique client ID. Two clients sharing an ID will disconnect each other in a loop. |
| 0x8F dec 143 | Topic Filter invalid | SUBACK, UNSUBACK, DISCONNECT | The topic filter is well-formed but not accepted by this server. Fix: Check wildcard placement (+ must fill a whole level, # must be last) and any broker limits on topic depth or length. |
| 0x90 dec 144 | Topic Name invalid | CONNACK, PUBACK, PUBREC, DISCONNECT | The topic name is well-formed but not accepted by the client or server. Fix: Never publish to a topic containing + or #, avoid empty topics, and check broker topic length/depth limits. |
| 0x91 dec 145 | Packet Identifier in use | PUBACK, PUBREC, SUBACK, UNSUBACK | The packet identifier is already in use for another in-flight exchange. Fix: Usually a client library bug or a session restored inconsistently. Update the library or start a clean session. |
| 0x92 dec 146 | Packet Identifier not found | PUBREL, PUBCOMP | The packet identifier is not known — the QoS 2 flow state was lost. Fix: Happens after session state is lost (e.g. clean start or broker restart without persistence). Enable persistence on the broker. |
| 0x93 dec 147 | Receive Maximum exceeded | DISCONNECT | More unacknowledged QoS 1/2 PUBLISH packets were sent than the receiver allowed. Fix: Respect the Receive Maximum from CONNACK/CONNECT; limit in-flight messages in your client settings. |
| 0x94 dec 148 | Topic Alias invalid | DISCONNECT | A topic alias was 0, larger than Topic Alias Maximum, or used before being defined. Fix: Respect the Topic Alias Maximum the other side announced, or disable topic aliases. |
| 0x95 dec 149 | Packet too large | CONNACK, DISCONNECT | The packet exceeds the maximum packet size allowed by the receiver. Fix: Shrink the payload (compress, split, or send a reference) or raise the broker message size limit. |
| 0x96 dec 150 | Message rate too high | DISCONNECT | The client is publishing faster than the server allows. Fix: Throttle publishes, batch readings into fewer messages, or raise the rate limit on the broker. |
| 0x97 dec 151 | Quota exceeded | CONNACK, PUBACK, PUBREC, SUBACK, DISCONNECT | An implementation or administrative quota was exceeded (messages, connections, storage, …). Fix: Check your plan or broker quotas, reduce message volume, or ask the operator to raise the limit. |
| 0x98 dec 152 | Administrative action | DISCONNECT | The connection was closed by an administrator. Fix: Contact the broker operator — someone kicked this client manually or via an admin API. |
| 0x99 dec 153 | Payload format invalid | CONNACK, PUBACK, PUBREC, DISCONNECT | The payload does not match the Payload Format Indicator (e.g. flagged as UTF-8 but not valid UTF-8). Fix: Only set Payload Format Indicator = 1 when the payload is valid UTF-8 text; send binary without it. |
| 0x9A dec 154 | Retain not supported | CONNACK, DISCONNECT | The server does not support retained messages, but the client sent one. Fix: Clear the retain flag on publishes and the Will Message, or use a broker that supports retain. |
| 0x9B dec 155 | QoS not supported | CONNACK, DISCONNECT | The client used a QoS higher than the Maximum QoS the server announced in CONNACK. Fix: Read Maximum QoS from CONNACK and publish (and set the Will QoS) at or below it. |
| 0x9C dec 156 | Use another server | CONNACK, DISCONNECT | The client should temporarily use another server. Fix: Read the Server Reference property and connect there; support redirection in your client if you run clusters. |
| 0x9D dec 157 | Server moved | CONNACK, DISCONNECT | The server has moved permanently; the client should use another server. Fix: Update the broker hostname in your configuration using the Server Reference property. |
| 0x9E dec 158 | Shared Subscriptions not supported | SUBACK, DISCONNECT | The server does not support $share/… shared subscriptions. Fix: Use normal subscriptions, or a broker with shared subscription support for load-balanced consumers. |
| 0x9F dec 159 | Connection rate exceeded | CONNACK, DISCONNECT | The client connects too often; the connection rate limit was hit. Fix: Add exponential backoff with jitter to reconnects and look for a reconnect loop (often caused by duplicate client IDs). |
| 0xA0 dec 160 | Maximum connect time | DISCONNECT | The maximum connection time allowed for this client has been reached. Fix: Reconnect; consider a persistent session so nothing is lost during the brief reconnect. |
| 0xA1 dec 161 | Subscription Identifiers not supported | SUBACK, DISCONNECT | The server does not support the Subscription Identifier property. Fix: Remove the Subscription Identifier from SUBSCRIBE and route messages by topic instead. |
| 0xA2 dec 162 | Wildcard Subscriptions not supported | SUBACK, DISCONNECT | The server does not support subscriptions containing + or # wildcards. Fix: Subscribe to exact topic names, or use a broker that supports wildcard subscriptions. |
MQTT 3.1.1 return codes
CONNACK return codes 0–5 and the SUBACK failure code from the MQTT 3.1.1 specification.
| Code | Name | Packets | Meaning & fix |
|---|---|---|---|
| 0 dec 0 | Connection Accepted | CONNACK | The broker accepted the connection. Fix: Nothing to fix. |
| 1 dec 1 | Connection Refused, unacceptable protocol version | CONNACK | The broker does not support the protocol level requested by the client. Fix: Set the client to MQTT 3.1.1 (level 4) or 3.1 (level 3) to match the broker. |
| 2 dec 2 | Connection Refused, identifier rejected | CONNACK | The client ID is valid UTF-8 but not allowed by the broker. Fix: Use 1–23 characters from [0-9a-zA-Z], or send an empty ID with clean session = true. |
| 3 dec 3 | Connection Refused, server unavailable | CONNACK | The network connection worked but the MQTT service is unavailable. Fix: Retry with backoff and check broker health. |
| 4 dec 4 | Connection Refused, bad user name or password | CONNACK | The username or password is malformed or wrong. Fix: Verify credentials and that the user exists in the broker auth backend. |
| 5 dec 5 | Connection Refused, not authorized | CONNACK | The client is not authorized to connect. Fix: Send credentials if anonymous access is disabled, and check the broker ACL for this user. |
| 0x80 dec 128 | Failure | SUBACK | The subscription was rejected — usually because of an ACL or an invalid topic filter. Fix: Check the filter syntax and that the user is allowed to subscribe to it. MQTT 3.1.1 gives no further detail; check the broker log. |
Reason code FAQ
What does MQTT reason code 0x87 (135) mean?
0x87 means Not authorized. On CONNACK the broker refused the connection (often because anonymous access is disabled and no credentials were sent). On PUBACK, SUBACK or DISCONNECT it means the user lacks permission for that topic in the broker ACL.
What is the difference between a reason code and a return code?
MQTT 3.1.1 only has return codes in CONNACK (0–5) and SUBACK (0x00–0x02 and 0x80). MQTT 5 replaced them with reason codes that appear in almost every acknowledgement, in DISCONNECT and in AUTH, and values of 0x80 or higher always indicate failure.
Why does my client keep disconnecting with 0x8E Session taken over?
Two connections are using the same client ID. When the second one connects, the broker disconnects the first. If both reconnect automatically they kick each other off in a loop. Give every device and browser tab a unique client ID.
Why do I get return code 5 in MQTT 3.1.1?
Return code 5 means Connection Refused, not authorized. The broker requires authentication or the user is blocked by its access rules. Send a valid username and password and check the broker ACL or allow_anonymous setting.