Quando um cliente MQTT falha com um vago "connection failed", a causa quase nunca é o MQTT em si. Normalmente é uma das quatro camadas abaixo dele: o DNS não resolveu o nome do broker, o TCP não alcançou a porta, um proxy ou firewall engoliu a conexão em silêncio, ou o TLS foi interceptado e o certificado não confere mais. Testar essas camadas em ordem — DNS → TCP → TLS → MQTT — encontra a camada quebrada em poucos minutos.
Este guia traz o comando exato para cada camada, as mensagens de erro que cada falha produz e um script Python que executa a cadeia inteira e mostra onde ela quebra.
Leia primeiro a mensagem de erro
O texto do erro já indica qual camada olhar. Estas são as mensagens mais pesquisadas:
| Erro | Camada | Causa comum |
|---|---|---|
getaddrinfo ENOTFOUND broker.connectmq.com (Node.js) | DNS | Host digitado errado, sem servidor DNS, DNS split-horizon |
[Errno -2] Name or service not known (Python, Linux) | DNS | Igual ao anterior |
[Errno 8] nodename nor servname provided, or not known (Python, macOS) | DNS | Igual ao anterior |
getaddrinfo EAI_AGAIN | DNS | Resolver inacessível ou com falha temporária |
connect ETIMEDOUT / TimeoutError: timed out | TCP / firewall | Pacotes descartados no caminho, IP errado, porta bloqueada |
connect ECONNREFUSED / [Errno 111] Connection refused | TCP | Host alcançável, nada escutando naquela porta |
ECONNRESET logo após conectar | Proxy / firewall | Um equipamento intermediário derrubou a conexão após inspecioná-la |
certificate verify failed: unable to get local issuer certificate | TLS | Falta o bundle de CAs ou há interceptação TLS |
self signed certificate in certificate chain | TLS | Proxy corporativo reassinando o tráfego |
Se você já recebe um CONNACK com reason code, a rede está ok e o problema é autenticação ou configuração — consulte a referência de reason codes.
Camada 1: resolução DNS
Verifique se o nome resolve, e se resolve para os mesmos endereços em todo lugar:
dig +short broker.connectmq.com A
dig +short broker.connectmq.com AAAA
# Compare com um resolver público para detectar split-horizon ou registros antigos
dig +short broker.connectmq.com @1.1.1.1
# Windows
nslookup broker.connectmq.comO que observar:
- Sem resposta — o nome não existe nesse resolver. Confira a grafia e se uma VPN ou o DNS corporativo sobrescreve zonas externas.
- Respostas diferentes entre o seu resolver e um público — DNS split-horizon, registro antigo em cache após uma migração de broker, ou um filtro DNS devolvendo o IP de uma página de bloqueio.
- Um registro AAAA sem rota IPv6 — o cliente tenta IPv6 primeiro e trava até fazer fallback. Veja problemas de IPv6 no MQTT.
Dentro de containers, o DNS vem do runtime, não do host. Rode o mesmo dig dentro do container (docker exec -it app sh) antes de supor que o resultado do host vale ali.
Camada 2: alcance TCP e roteamento
A resolução funciona; agora abra uma conexão TCP direta em cada porta MQTT que você pode usar:
nc -vz -w 5 broker.connectmq.com 1883 # MQTT sobre TCP
nc -vz -w 5 broker.connectmq.com 8883 # MQTT sobre TLS
nc -vz -w 5 broker.connectmq.com 8084 # MQTT sobre WebSockets segurosTest-NetConnection broker.connectmq.com -Port 8883A diferença entre um timeout e uma recusa é o sinal mais útil na depuração de rede:
succeeded/TcpTestSucceeded : True— o caminho está aberto; siga para o TLS.Connection refused— você chegou ao host, mas nada escuta ali. Porta errada ou broker fora do ar.- Trava e depois dá timeout — algo entre você e o broker descarta os pacotes. Quase sempre é um firewall.
Para ver onde os pacotes param, trace a rota na porta real, não com ICMP (que muitas redes tratam de forma diferente):
sudo traceroute -T -p 8883 broker.connectmq.com # Linux
mtr --tcp --port 8883 broker.connectmq.com # se o mtr estiver instaladoSe o trace morre no seu próprio gateway ou no primeiro salto corporativo, o bloqueio é local. Se morre longe, o problema está mais adiante ou na borda do broker. Um passo a passo completo está em testar se uma porta MQTT está aberta, e os números de porta padrão estão em portas MQTT.
Camada 3: firewalls e proxies
Redes de escritório, hotel e nuvem muitas vezes só liberam HTTP(S) de saída, através de um proxy explícito. Clientes MQTT não leem HTTP_PROXY por padrão, então a conexão direta simplesmente dá timeout.
Primeiro, descubra se há um proxy configurado:
env | grep -i _proxy
# Windows: netsh winhttp show proxyDepois verifique se o proxy faz túnel até a porta do broker com um CONNECT HTTP:
nc -X connect -x proxy.example.corp:3128 -vz broker.connectmq.com 8883Se o proxy recusa CONNECT na 8883 mas libera a 443, você tem duas opções: usar MQTT sobre WebSockets seguros em uma porta que o proxy permita, ou pedir à equipe de rede que libere o host do broker. Clientes no navegador passam automaticamente pelo proxy do sistema, e é por isso que o cliente MQTT online costuma funcionar em redes onde um cliente nativo falha. Mais estratégias em MQTT atrás de um firewall corporativo e MQTT na porta 443.
Camada 4: TLS e interceptação
A porta TCP está aberta, mas o TLS falha. Veja o certificado que o cliente realmente recebe:
openssl s_client -connect broker.connectmq.com:8883 \
-servername broker.connectmq.com -showcerts </dev/null 2>/dev/null \
| openssl x509 -noout -subject -issuer -datesCompare a linha issuer com o que você obtém pelo hotspot do celular ou pela rede de casa. Se no escritório o emissor for o nome da sua empresa ou de um fornecedor de segurança, um proxy com inspeção TLS está reassinando a conexão. Seu cliente MQTT a rejeita com certificate verify failed ou self signed certificate in certificate chain — e esse é o comportamento correto.
Correções, em ordem de preferência:
- Peça que o host do broker seja excluído da inspeção TLS (MQTT não é HTTP, e muitos produtos de inspeção o quebram de qualquer forma).
- Se a política exige inspeção, adicione a CA raiz corporativa ao trust store do cliente — nunca desative a verificação de certificado.
- Garanta que o cliente envia SNI (o
-servernameacima): sem ele, alguns endpoints devolvem outro certificado, o que gera erros de hostname mismatch.
Se o handshake trava em vez de falhar, principalmente em VPN, desconfie de um problema de MTU: pacotes pequenos passam, mas a mensagem grande do certificado é descartada. Testar com um MTU menor na interface confirma. Erros de TLS em geral estão em MQTT TLS handshake failed.
Rode a cadeia inteira com um script
Este script (Python 3.8+, paho-mqtt 2.x) testa cada camada em ordem, para na primeira falha e imprime o tempo de cada etapa:
import os, socket, ssl, sys, time
import paho.mqtt.client as mqtt
HOST, PORT = "broker.connectmq.com", 8883
def dns():
infos = socket.getaddrinfo(HOST, PORT, proto=socket.IPPROTO_TCP)
return ", ".join(sorted({i[4][0] for i in infos}))
def tcp():
with socket.create_connection((HOST, PORT), timeout=5) as s:
return f"connected to {s.getpeername()[0]}"
def tls():
ctx = ssl.create_default_context()
with socket.create_connection((HOST, PORT), timeout=5) as raw:
with ctx.wrap_socket(raw, server_hostname=HOST) as s:
issuer = dict(x[0] for x in s.getpeercert()["issuer"])
return f"{s.version()}, issuer: {issuer.get('organizationName')}"
def mqtt_connect():
result = {}
c = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, protocol=mqtt.MQTTv5)
c.on_connect = lambda cl, ud, flags, reason, props: result.setdefault("rc", reason)
if os.getenv("MQTT_USER"):
c.username_pw_set(os.getenv("MQTT_USER"), os.getenv("MQTT_PASS"))
c.tls_set()
c.connect(HOST, PORT, keepalive=30)
c.loop_start()
for _ in range(50):
if "rc" in result:
break
time.sleep(0.1)
c.disconnect()
c.loop_stop()
if "rc" not in result:
raise TimeoutError("no CONNACK within 5 s")
if result["rc"].is_failure:
raise RuntimeError(f"CONNACK: {result['rc']}")
return f"CONNACK: {result['rc']}"
for name, step in [("DNS", dns), ("TCP", tcp), ("TLS", tls), ("MQTT", mqtt_connect)]:
start = time.perf_counter()
try:
info = step()
except Exception as e:
print(f"FAIL {name:<5} {type(e).__name__}: {e}")
sys.exit(1)
print(f"OK {name:<5} {(time.perf_counter() - start) * 1000:6.0f} ms {info}")Uma execução saudável imprime quatro linhas OK. Uma falha mostra a camada e a exceção exata, que corresponde diretamente à tabela do início deste artigo. Rode na máquina que tem o problema — um notebook em outra rede não prova nada sobre o dispositivo que falha.
Confirme a correção
Depois de mudar DNS, regras de firewall ou configurações de proxy, verifique de ponta a ponta em vez de confiar na mudança:
- Rode
netcheck.pyde novo na máquina afetada e confirme que as quatro camadas passam. - Assine um topic de teste no cliente online e publique nele a partir do dispositivo afetado.
- Deixe a conexão ociosa por mais tempo que o timeout suspeito do firewall e confira se as mensagens continuam chegando.
Abra o cliente online para testar a entrega
Problemas de rede parecem aleatórios até você separá-los em camadas. Resolva o nome, abra o socket, inspecione o certificado e só então fale MQTT — a primeira etapa que falhar é a que precisa de correção, e a mensagem de erro geralmente já diz qual é.
Perguntas frequentes
Por que meu cliente MQTT funciona em casa mas não no escritório?
Redes corporativas costumam bloquear portas de saída como 1883 e 8883, forçar o tráfego por um proxy HTTP ou inspecionar o TLS. Teste cada camada a partir da rede do escritório: DNS, uma conexão TCP direta, o emissor do certificado TLS e depois o MQTT. MQTT sobre WebSockets na porta 443 costuma ser a saída.
Como saber se um firewall está descartando o tráfego MQTT?
Um firewall que descarta pacotes gera um timeout (ETIMEDOUT, 'timed out'), enquanto uma porta fechada em um host alcançável responde na hora com 'Connection refused'. Rode nc -vz ou Test-NetConnection contra a porta e compare com outra porta do mesmo host.
Como detectar interceptação TLS na minha rede?
Rode openssl s_client contra o broker e imprima o emissor do certificado. Se o emissor for a CA da sua empresa ou de um produto de segurança em vez de uma CA pública, a conexão está sendo interceptada e seu cliente vai falhar na verificação do certificado, a menos que confie nessa CA.

