Os reason codes MQTT são os valores de status de um byte que brokers e clients MQTT 5 colocam nas confirmações e nos pacotes DISCONNECT para dizer exatamente o que aconteceu. Esta referência lista todos os códigos, quais pacotes podem carregá-los, o que costuma provocá-los e como corrigi-los, para que você transforme um enigmático 0x87 ou 0x97 nos seus logs em um próximo passo concreto.
Como funcionam os reason codes MQTT
O MQTT 3.1.1 tinha apenas alguns valores de status: seis return codes no CONNACK e um único valor de falha (0x80) no SUBACK. Todo o resto, como um publish rejeitado ou uma desconexão iniciada pelo broker, era silencioso; a conexão simplesmente era fechada. O MQTT 5 substituiu isso por um conjunto compartilhado de reason codes usado em CONNACK, PUBACK, PUBREC, PUBREL, PUBCOMP, SUBACK, UNSUBACK, DISCONNECT e AUTH. É um dos recursos do MQTT 5 mais práticos para quem opera dispositivos em campo.
Duas regras tornam a tabela fácil de ler:
- Valores abaixo de
0x80significam sucesso ou um resultado que não é erro, como "QoS 1 concedido" ou "nenhum assinante correspondente". - Valores de
0x80para cima significam falha. O pacote que carrega o código indica qual operação falhou.
Muitos pacotes também podem carregar uma propriedade Reason String, uma explicação legível por humanos enviada pelo remetente. Sempre a registre em log quando estiver presente; ela muitas vezes contém o limite exato que foi atingido.
Códigos de sucesso e informativos
| Código | Nome | Pacotes | O que significa |
|---|---|---|---|
| 0x00 | Success / Normal disconnection / Granted QoS 0 | CONNACK, PUBACK, PUBREC, PUBREL, PUBCOMP, UNSUBACK, AUTH, DISCONNECT, SUBACK | A operação foi bem-sucedida; no SUBACK significa que a assinatura foi concedida em QoS 0 |
| 0x01 | Granted QoS 1 | SUBACK | Assinatura aceita com QoS máximo 1 |
| 0x02 | Granted QoS 2 | SUBACK | Assinatura aceita com QoS máximo 2 |
| 0x04 | Disconnect with Will Message | DISCONNECT | O client está saindo de forma limpa, mas pede ao broker que publique seu Will |
| 0x10 | No matching subscribers | PUBACK, PUBREC | Publish aceito, mas ninguém estava inscrito |
| 0x11 | No subscription existed | UNSUBACK | Você cancelou a assinatura de um filtro no qual não estava inscrito |
| 0x18 | Continue authentication | AUTH | A troca de autenticação aprimorada continua |
| 0x19 | Re-authenticate | AUTH | O client inicia uma reautenticação em uma conexão existente |
Um SUBACK que concede um QoS menor do que o solicitado não é um erro. Se você pede QoS 2 e recebe 0x01, o QoS máximo do broker para a sua conexão é 1, e as mensagens chegarão no máximo em QoS 1.
Referência dos reason codes de erro
| Código | Nome | Pacotes | Causa habitual | Solução |
|---|---|---|---|---|
| 0x80 | Unspecified error | Todas as confirmações, DISCONNECT | O broker recusou sem um motivo específico | Leia a Reason String e os logs do broker |
| 0x81 | Malformed Packet | CONNACK, DISCONNECT | Codificação inválida, UTF-8 incorreto, comprimentos errados | Atualize a biblioteca do client; verifique encoders personalizados |
| 0x82 | Protocol Error | CONNACK, DISCONNECT | Pacote válido, mas enviado fora de ordem ou com campos proibidos | Procure CONNECT duplicado ou uso indevido de propriedades |
| 0x83 | Implementation specific error | CONNACK, PUBACK, PUBREC, SUBACK, UNSUBACK, DISCONNECT | Uma política específica do broker rejeitou a operação | Consulte a documentação do broker e a Reason String |
| 0x84 | Unsupported Protocol Version | CONNACK | O broker não fala a versão solicitada | Use MQTT 3.1.1 ou 5.0, conforme suportado |
| 0x85 | Client Identifier not valid | CONNACK | Client ID vazio, longo demais ou não permitido | Use um client ID válido e único |
| 0x86 | Bad User Name or Password | CONNACK | Credenciais erradas ou malformadas | Copie de novo o username e o password |
| 0x87 | Not authorized | CONNACK, PUBACK, PUBREC, SUBACK, UNSUBACK, DISCONNECT | As credenciais ou o client não têm permissão | Verifique credenciais, vínculo do client ID e permissões de topic |
| 0x88 | Server unavailable | CONNACK | O broker não pode aceitar conexões no momento | Tente de novo com backoff |
| 0x89 | Server busy | CONNACK, DISCONNECT | O broker está sobrecarregado | Tente mais tarde com backoff e jitter |
| 0x8A | Banned | CONNACK | O client ou o endereço está bloqueado | Interrompa os loops de retentativa; corrija as credenciais; contate o operador |
| 0x8B | Server shutting down | DISCONNECT | Desligamento ou reinício planejado | Reconecte com backoff |
| 0x8C | Bad authentication method | CONNACK, DISCONNECT | Método de autenticação aprimorada não suportado | Remova ou corrija o Authentication Method |
| 0x8D | Keep Alive timeout | DISCONNECT | Nenhum pacote recebido em 1,5 x keep alive | Mantenha o loop de rede rodando; verifique a conectividade |
| 0x8E | Session taken over | DISCONNECT | Outro client se conectou com o mesmo client ID | Dê a cada client um ID único |
| 0x8F | Topic Filter invalid | SUBACK, UNSUBACK, DISCONNECT | Filtro malformado, por exemplo a/#/b |
Corrija a posição dos wildcards |
| 0x90 | Topic Name invalid | CONNACK, PUBACK, PUBREC, DISCONNECT | Wildcards ou caracteres inválidos em um topic de publish | Publique em um nome de topic concreto |
| 0x91 | Packet Identifier in use | PUBACK, PUBREC, SUBACK, UNSUBACK | Packet ID reutilizado enquanto ainda estava em trânsito | Bug da biblioteca ou tratamento personalizado de packet IDs |
| 0x92 | Packet Identifier not found | PUBREL, PUBCOMP | Estado do QoS 2 perdido, muitas vezes após um reset de sessão | Verifique as configurações de persistência de sessão |
| 0x93 | Receive Maximum exceeded | DISCONNECT | Publishes QoS 1/2 não confirmados demais | Respeite o Receive Maximum do outro lado |
| 0x94 | Topic Alias invalid | DISCONNECT | Alias fora do intervalo ou não definido | Reinicie os aliases ao reconectar; respeite o máximo |
| 0x95 | Packet too large | CONNACK, DISCONNECT | O pacote excede o Maximum Packet Size | Reduza ou divida os payloads |
| 0x96 | Message rate too high | DISCONNECT | Publicando mais rápido que o permitido | Limite a taxa de publishes |
| 0x97 | Quota exceeded | CONNACK, PUBACK, PUBREC, SUBACK, DISCONNECT | Um limite do plano ou da conta foi atingido | Reduza o uso ou faça upgrade do plano |
| 0x98 | Administrative action | DISCONNECT | Um operador desconectou o client | Consulte o administrador do broker |
| 0x99 | Payload format invalid | CONNACK, PUBACK, PUBREC, DISCONNECT | O Payload Format Indicator diz UTF-8, mas os bytes não são | Corrija a codificação ou remova o indicador |
| 0x9A | Retain not supported | CONNACK, DISCONNECT | Flag retain usada onde não é permitida | Publique sem retain |
| 0x9B | QoS not supported | CONNACK, DISCONNECT | QoS do publish acima do máximo do broker | Reduza o QoS ao máximo anunciado |
| 0x9C | Use another server | CONNACK, DISCONNECT | O broker redireciona o client temporariamente | Siga a propriedade Server Reference |
| 0x9D | Server moved | CONNACK, DISCONNECT | O broker redireciona permanentemente | Atualize o host configurado |
| 0x9E | Shared Subscriptions not supported | SUBACK, DISCONNECT | Filtro $share/... não permitido |
Use um plano ou broker com shared subscriptions |
| 0x9F | Connection rate exceeded | CONNACK | Tentativas de conexão demais | Adicione backoff à lógica de reconexão |
| 0xA0 | Maximum connect time | DISCONNECT | Limite de duração da conexão atingido | Reconecte; espere desconexões periódicas |
| 0xA1 | Subscription Identifiers not supported | SUBACK, DISCONNECT | Propriedade Subscription Identifier não permitida | Remova a propriedade |
| 0xA2 | Wildcard Subscriptions not supported | SUBACK, DISCONNECT | Wildcards não permitidos para este client | Assine topics explícitos |
Note que alguns códigos, como 0x8D e 0x8E, aparecem apenas em um DISCONNECT enviado pelo broker. Outros, como 0x84 a 0x88, só podem aparecer no CONNACK, porque descrevem por que a conexão foi recusada logo de início.
Mapeando return codes do MQTT 3.1.1 para o MQTT 5
Se você suporta as duas versões do protocolo, este mapeamento mantém seu tratamento de erros consistente. O passo a passo detalhado está no guia de return codes do CONNACK no MQTT.
| CONNACK do MQTT 3.1.1 | Equivalente no MQTT 5 |
|---|---|
| 0 Connection accepted | 0x00 Success |
| 1 Unacceptable protocol version | 0x84 Unsupported Protocol Version |
| 2 Identifier rejected | 0x85 Client Identifier not valid |
| 3 Server unavailable | 0x88 Server unavailable |
| 4 Bad user name or password | 0x86 Bad User Name or Password |
| 5 Not authorized | 0x87 Not authorized |
Registrando reason codes MQTT em Python
Com paho-mqtt 2.x e CallbackAPIVersion.VERSION2, todo callback recebe um objeto ReasonCode. Sua forma em string é o nome da especificação e .value é o código numérico, exatamente o que você quer nos logs:
import paho.mqtt.client as mqtt
def on_connect(client, userdata, flags, reason_code, properties):
print(f"CONNACK: {reason_code} (0x{reason_code.value:02X})")
if reason_code.is_failure:
return
client.subscribe("connectmq/demo/b7d2/#", qos=2)
def on_subscribe(client, userdata, mid, reason_code_list, properties):
for rc in reason_code_list:
print(f"SUBACK: {rc} (0x{rc.value:02X})")
def on_disconnect(client, userdata, flags, reason_code, properties):
reason = getattr(properties, "ReasonString", None) if properties else None
print(f"DISCONNECT: {reason_code} (0x{reason_code.value:02X}) {reason or ''}")
client = mqtt.Client(
mqtt.CallbackAPIVersion.VERSION2,
client_id="reason-demo-b7d2",
protocol=mqtt.MQTTv5,
)
client.on_connect = on_connect
client.on_subscribe = on_subscribe
client.on_disconnect = on_disconnect
client.connect("broker.connectmq.com", 1883, keepalive=30)
client.loop_forever()
Rode isso contra o servidor MQTT público e você verá Success na conexão e um QoS concedido no SUBACK. Tente assinar um filtro inválido, como connectmq/demo/b7d2/#/x, para ver o 0x8F Topic Filter invalid em ação. Com o MQTT.js, a mesma informação está em connack.reasonCode, no array granted do callback de subscribe e no pacote do evento disconnect.
Fluxo de depuração por reason code
Uma ordem prática para investigar uma falha:
- Identifique o pacote. Um código no CONNACK é um problema de conexão; no SUBACK, um problema de assinatura; no DISCONNECT, um problema em tempo de execução.
- Leia a Reason String. Ela geralmente restringe a causa a um limite ou regra específica.
- Verifique primeiro as credenciais e a identidade para
0x85,0x86e0x87. O guia para corrigir MQTT connection refused: not authorized aborda isso em profundidade. - Verifique os limites para
0x93,0x95,0x96e0x97: tamanho de mensagem, taxa, número de conexões e mensagens em trânsito. - Verifique a higiene da frota para
0x8E: client IDs duplicados são a causa mais comum de loops de desconexão.
Reason codes no ConnectMQ
O ConnectMQ suporta MQTT 3.1.1 e 5.0, então clients MQTT 5 recebem os reason codes acima. As cotas dos planos aparecem como 0x97 Quota exceeded, por exemplo quando um broker Serverless gratuito já atingiu seu máximo de 25 conexões. Os recursos do plano também importam: o plano gratuito concede QoS até 1, então uma assinatura em QoS 2 é concedida com um QoS menor no SUBACK, enquanto QoS 2 e shared subscriptions vêm com o plano Serverless pago. Falhas repetidas de login são tratadas como suspeitas, e o IP de origem pode ser bloqueado, então nunca deixe um client tentando credenciais erradas em um loop apertado.
Para entender o que um broker MQTT faz com esses códigos, ou o protocolo completo em contexto, veja o tutorial de MQTT.
Depure mais rápido com o ConnectMQ
Um broker MQTT gerenciado com client integrado ao navegador e explorador de topics ao vivo torna muito mais rápido reproduzir um publish ou uma assinatura com falha. Crie um broker Serverless gratuito em app.connectmq.com, sem cartão de crédito, e teste seu tratamento de erros contra respostas reais do MQTT 5.
Perguntas frequentes
Qual é a diferença entre reason code e return code?
Return code é o termo do MQTT 3.1.1 para os seis valores do CONNACK. O MQTT 5 generalizou a ideia em reason codes que aparecem em quase todas as confirmações e no DISCONNECT.
Quais reason codes significam sucesso?
Qualquer valor abaixo de 0x80. Isso inclui 0x00 Success, 0x01 e 0x02 para QoS concedido e valores informativos como 0x10 No matching subscribers.
O que significa o reason code MQTT 0x97?
0x97 é Quota exceeded: o client atingiu um limite, como o máximo de conexões ou uma restrição do plano. Reduza o uso ou migre para um plano com limites maiores.
Clients MQTT 3.1.1 recebem reason codes do MQTT 5?
Não. Uma conexão 3.1.1 só recebe os return codes clássicos do CONNACK e o valor de falha 0x80 no SUBACK. Conecte-se com a versão 5 do protocolo para receber reason codes detalhados.



