Fundamentos de MQTT

Como Corrigir "MQTT Connection Refused: Not Authorized" (rc 5 e 0x87)

Recebendo "Connection Refused: not authorised" ou o reason code 0x87? Siga este checklist sobre credenciais, vínculo do client ID, portas e TLS e contas por broker para encontrar a causa rapidamente.

Broker rejeitando o login de um dispositivo para ilustrar o erro MQTT conexão recusada não autorizado
Rode isso no seu próprio broker MQTTTenha um broker MQTT privado e gerenciado no plano Free e comece com exemplos de código prontos.
Teste grátis Exemplos de código Sem cartão de crédito

"MQTT connection refused: not authorized" (MQTT conexão recusada, não autorizado) significa que o broker recebeu seu pacote CONNECT, o entendeu e decidiu que este client não pode se conectar. No MQTT 3.1.1 isso é o código de retorno 5 do CONNACK; no MQTT 5 é o reason code 0x87. Este guia traz um checklist passo a passo para encontrar a causa, de credenciais e client IDs a confusões de porta e contas por broker, e mostra como testar cada passo pela linha de comando.

O que "Not Authorized" realmente diz

O erro é mais informativo do que parece. Para recebê-lo, várias coisas já precisam estar funcionando:

  • O DNS resolveu o host do broker.
  • A conexão TCP, e o TLS se usado, foi estabelecida.
  • O broker interpretou um pacote CONNECT válido.
  • A versão do protocolo foi aceita.

Então a rede está bem. O problema é de identidade ou permissão. Você o verá escrito de formas diferentes dependendo da ferramenta:

Ferramenta Mensagem típica
mosquitto_pub / mosquitto_sub Connection error: Connection Refused: not authorised.
Paho Python 2.x reason_code igual a Not authorized no on_connect
MQTT.js Connection refused: Not authorized (err.code === 5) ou reason code 135 com MQTT 5
Nó MQTT do Node-RED O status mostra "connecting" e o log informa connection refused, not authorized

Vale separar logo cedo um código relacionado. O código de retorno 4 (0x86 no MQTT 5) significa "bad user name or password": as próprias credenciais não conferem. O código 5 (0x87) é mais amplo: o broker recusa este client por um motivo de autorização. Alguns brokers também retornam 5 para senhas erradas, então trate os dois como "verificar identidade", mas leia o código exato. O guia de códigos de retorno do CONNACK MQTT explica cada valor.

Checklist de solução de problemas de Not Authorized

Siga estes passos na ordem. A maioria dos casos se resolve até o passo 3.

  1. Confirme a qual broker você está se conectando. Imprima o host e a porta que seu código realmente usa em tempo de execução, não os que você acha que estão configurados. Variáveis de ambiente e arquivos de configuração frequentemente se sobrepõem.
  2. Copie as credenciais de novo. Cole o username e o password direto da página de credenciais do broker. Procure espaços no início ou no fim, quebras de linha vindas da cópia e username e password trocados.
  3. Use o client ID que pertence às credenciais. Muitos brokers MQTT gerenciados vinculam um client ID à conta emitida. Se seu código gera um ID aleatório ou reutiliza um de outro projeto, o broker pode recusá-lo mesmo com o password correto.
  4. Verifique se a biblioteca envia as credenciais. No Paho, username_pw_set() precisa ser chamado antes de connect(). No PubSubClient do Arduino, use a sobrecarga connect(clientId, user, pass), e não connect(clientId).
  5. Verifique as aspas do shell. Passwords com $, ! ou & são alterados pelo Bash. Use aspas simples: -P 'p@ss$word!'.
  6. Verifique a porta e o transporte. A porta 1883 é TCP simples, a 8883 é TLS, a 8083 é WebSocket e a 8084 é WebSocket seguro com o caminho /mqtt. Uma incompatibilidade geralmente produz um timeout ou erro de TLS, e não "not authorized", mas um client mal configurado pode acabar conversando com um listener ou ambiente diferente do pretendido.
  7. Confirme que a conta está ativa. As credenciais podem ter sido regeneradas, um broker pode ter sido apagado ou recriado, ou você pode estar usando credenciais de staging em produção.
  8. Verifique as cotas de conexão. Se o limite de conexões do plano for atingido, clients MQTT 5 recebem 0x97 Quota exceeded, mas algumas bibliotecas 3.1.1 mostram qualquer recusa de forma genérica. Conte suas conexões ativas.
  9. Pare de tentar em loop. Cada tentativa malsucedida é um login com falha do ponto de vista do broker. Aumente o intervalo entre tentativas enquanto investiga.

Testando as credenciais pela linha de comando

Isole sua aplicação do problema testando exatamente as mesmas credenciais com as ferramentas do Mosquitto. Primeiro, comprove que o caminho de rede funciona com o servidor MQTT público, que é anônimo e serve apenas para testes:

mosquitto_sub -h broker.connectmq.com -p 1883 -i auth-check-2d9f \
  -t "connectmq/demo/2d9f/#" -d -C 1 -W 5

Se você vir received CONNACK (0), sua máquina alcança o broker e fala MQTT. Em seguida, teste suas credenciais privadas sobre TLS:

mosquitto_sub -h broker.connectmq.com -p 8883 --capath /etc/ssl/certs \
  -u 'YOUR_USERNAME' -P 'YOUR_PASSWORD' -i 'YOUR_CLIENT_ID' \
  -t "test/#" -d -V mqttv5

Com -V mqttv5, uma recusa imprime o reason code do MQTT 5, que é mais específico que o código do 3.1.1. Se este comando conecta, mas sua aplicação não, o problema está na configuração da aplicação, não na conta. Se este comando também falha, o problema está nas credenciais, no client ID ou na conta.

No Windows, --capath não está disponível da mesma forma; use --cafile com um arquivo de bundle de CAs, ou teste com um client MQTT gráfico.

Corrigindo no código

Aqui está um client Python que imprime a configuração que realmente está usando e para nos erros de autorização em vez de tentar para sempre:

import os
import ssl
import paho.mqtt.client as mqtt

HOST = os.getenv("MQTT_HOST", "broker.connectmq.com")
PORT = int(os.getenv("MQTT_PORT", "8883"))
USERNAME = os.getenv("MQTT_USERNAME", "YOUR_USERNAME")
PASSWORD = os.getenv("MQTT_PASSWORD", "YOUR_PASSWORD")
CLIENT_ID = os.getenv("MQTT_CLIENT_ID", "YOUR_CLIENT_ID")

print(f"Connecting to {HOST}:{PORT} as user={USERNAME!r} client_id={CLIENT_ID!r}")

def on_connect(client, userdata, flags, reason_code, properties):
    if reason_code.is_failure:
        print(f"Refused: {reason_code} (0x{reason_code.value:02X})")
        if reason_code.value in (0x85, 0x86, 0x87):
            print("Identity problem: check username, password and client ID")
            client.disconnect()
        return
    print("Connected")

client = mqtt.Client(
    mqtt.CallbackAPIVersion.VERSION2,
    client_id=CLIENT_ID,
    protocol=mqtt.MQTTv5,
)
client.username_pw_set(USERNAME, PASSWORD)
client.tls_set(cert_reqs=ssl.CERT_REQUIRED)
client.on_connect = on_connect
client.connect(HOST, PORT, keepalive=60)
client.loop_forever()

A formatação !r imprime os valores entre aspas, o que deixa espaços invisíveis evidentes. Essa única linha já resolveu muitas investigações do tipo "meu password com certeza está certo".

Em um ESP32 com PubSubClient, o erro comum é a sobrecarga:

// Errado: nenhuma credencial é enviada
mqtt.connect("YOUR_CLIENT_ID");

// Certo: client ID, username e password
mqtt.connect("YOUR_CLIENT_ID", "YOUR_USERNAME", "YOUR_PASSWORD");

Not Authorized depois de conectar

Às vezes a conexão funciona, mas operações posteriores falham com "not authorized". No MQTT 5 você verá 0x87 em um SUBACK ou PUBACK, ou em um DISCONNECT. Isso significa que o client pode se conectar, mas não tem permissão para usar um topic específico, por exemplo um prefixo reservado. No MQTT 3.1.1 não há reason code para um publish rejeitado, então a mensagem pode simplesmente desaparecer. Se mensagens somem, conecte-se temporariamente com MQTT 5 para ver o reason code real. A referência de reason codes do MQTT lista todos os códigos por tipo de pacote.

Como isso funciona no ConnectMQ

No ConnectMQ, cada broker que você cria no portal recebe username, password e client ID gerados, e o client ID é vinculado a essas credenciais. Essa é a primeira coisa a verificar quando você vê 0x87: você está usando os três valores do mesmo broker? Os brokers são isolados por tenant, então as credenciais de um broker não funcionam em outro, mesmo dentro da mesma conta.

Vale conhecer mais dois comportamentos da plataforma:

  • Logins com falha têm limite de taxa. Após repetidas falhas de login, o endereço IP de origem é bloqueado. Um dispositivo preso em um loop de reconexão apertado com credenciais desatualizadas pode bloquear outros dispositivos atrás do mesmo NAT. Use backoff exponencial.
  • Os limites de conexão são por plano. O plano Serverless gratuito permite até 25 conexões simultâneas. Ultrapassá-lo produz 0x97 Quota exceeded para clients MQTT 5, e não "not authorized", o que é mais um motivo para preferir o MQTT 5 durante a depuração.

Para ir além da autenticação, veja as boas práticas de segurança MQTT e, para a visão mais ampla do protocolo, o tutorial de MQTT.

Conecte-se com segurança ao ConnectMQ

Um broker MQTT gerenciado que emite credenciais e client IDs correspondentes elimina a maioria das causas deste erro antes que elas aconteçam. Cadastre-se em app.connectmq.com para ter um broker Serverless gratuito, sem cartão de crédito, e use o client MQTT integrado ao navegador para confirmar que suas credenciais funcionam antes de gravar o firmware de um único dispositivo. Saiba mais sobre como rodar um broker MQTT na nuvem.

Perguntas frequentes

O que significa "Connection Refused: not authorised" nas ferramentas do Mosquitto?

É o código de retorno 5 do CONNACK. O broker recebeu um CONNECT válido, mas recusou o client, geralmente por credenciais erradas, um client ID não vinculado à conta ou credenciais de outro broker.

"Not authorized" é o mesmo que "bad username or password"?

Não exatamente. Bad username or password é o código 4 (0x86) e significa que as credenciais não conferem; not authorized é o código 5 (0x87) e abrange problemas de permissão mais amplos. Alguns brokers usam o código 5 para os dois casos, então verifique as credenciais primeiro de qualquer forma.

Por que meu client conecta com o mosquitto_sub, mas não pela minha aplicação?

A aplicação está enviando algo diferente: outro host, um client ID gerado, credenciais ausentes ou um password alterado. Imprima a configuração efetiva em tempo de execução e compare com o comando que funciona.

Logins com falha repetidos podem causar problemas?

Sim. Muitos brokers, incluindo o ConnectMQ, bloqueiam endereços IP após repetidas falhas de login. Use backoff exponencial e pare de tentar em erros de autorização.

Artigos relacionados

Por que Seu Cliente MQTT Fica Desconectando (e Como Corrigir)

Loops de reconexão estão entre os problemas mais comuns do MQTT. Conheça as cinco causas habituais, de client IDs duplicados a timeouts de keep alive e pacotes grandes demais, e siga um fluxo de diagnóstico que identifica a sua.

9 min de leitura

Quem Inventou o MQTT? A História dos Oleodutos à IoT

O MQTT foi inventado em 1999 por Andy Stanford-Clark, da IBM, e Arlen Nipper, da Arcom, para monitorar oleodutos via satélite. Acompanhe sua trajetória até o open source, a OASIS, a ISO e os brokers MQTT gerenciados na nuvem de hoje.

8 min de leitura

Todos os artigos →

Seu broker MQTT privado está a poucos cliques de distância

Crie uma conta, receba as credenciais do seu broker e conecte seu primeiro dispositivo — sem servidores para instalar, atualizar ou escalar.