Wenn ein MQTT-Client mit einem vagen „connection failed" scheitert, liegt es selten an MQTT selbst. Meist ist eine der vier Schichten darunter schuld: DNS konnte den Broker-Namen nicht auflösen, TCP erreichte den Port nicht, ein Proxy oder eine Firewall hat die Verbindung stillschweigend geschluckt, oder TLS wurde abgefangen und das Zertifikat passt nicht mehr. Wenn du diese Schichten der Reihe nach testest — DNS → TCP → TLS → MQTT —, findest du die kaputte in wenigen Minuten.
Diese Anleitung liefert dir den genauen Befehl für jede Schicht, die Fehlermeldungen, die jeder Fehler erzeugt, und ein Python-Skript, das die ganze Kette durchläuft und dir sagt, wo sie bricht.
Zuerst die Fehlermeldung lesen
Der Fehlertext verrät bereits, welche Schicht du dir ansehen musst. Das sind die am häufigsten gesuchten Meldungen:
| Fehler | Schicht | Typische Ursache |
|---|---|---|
getaddrinfo ENOTFOUND broker.connectmq.com (Node.js) | DNS | Tippfehler im Host, kein DNS-Server, Split-Horizon-DNS |
[Errno -2] Name or service not known (Python, Linux) | DNS | Wie oben |
[Errno 8] nodename nor servname provided, or not known (Python, macOS) | DNS | Wie oben |
getaddrinfo EAI_AGAIN | DNS | Resolver nicht erreichbar oder vorübergehend gestört |
connect ETIMEDOUT / TimeoutError: timed out | TCP / Firewall | Pakete unterwegs verworfen, falsche IP, blockierter Port |
connect ECONNREFUSED / [Errno 111] Connection refused | TCP | Host erreichbar, aber nichts lauscht auf dem Port |
ECONNRESET direkt nach dem Verbinden | Proxy / Firewall | Eine Middlebox hat die Verbindung nach der Inspektion getrennt |
certificate verify failed: unable to get local issuer certificate | TLS | Fehlendes CA-Bundle oder TLS-Interception |
self signed certificate in certificate chain | TLS | Firmen-Proxy signiert den Traffic neu |
Bekommst du bereits ein CONNACK mit Reason Code, ist das Netzwerk in Ordnung und das Problem liegt bei Authentifizierung oder Konfiguration — schlag ihn in der Reason-Code-Referenz nach.
Schicht 1: DNS-Auflösung
Prüfe, ob der Name aufgelöst wird — und zwar überall auf dieselben Adressen:
dig +short broker.connectmq.com A
dig +short broker.connectmq.com AAAA
# Mit einem öffentlichen Resolver vergleichen, um Split-Horizon oder veraltete Einträge zu finden
dig +short broker.connectmq.com @1.1.1.1
# Windows
nslookup broker.connectmq.comWorauf du achten solltest:
- Keine Antwort — der Name existiert in diesem Resolver nicht. Prüfe die Schreibweise und ob ein VPN oder das Firmen-DNS externe Zonen überschreibt.
- Unterschiedliche Antworten von deinem und einem öffentlichen Resolver — Split-Horizon-DNS, ein alter gecachter Eintrag nach einer Broker-Migration oder ein DNS-Filter, der die IP einer Sperrseite liefert.
- Ein AAAA-Eintrag, aber keine IPv6-Route — der Client versucht zuerst IPv6 und hängt, bis er zurückfällt. Siehe MQTT-IPv6-Probleme.
In Containern kommt DNS von der Container-Runtime, nicht vom Host. Führe dasselbe dig im Container aus (docker exec -it app sh), bevor du annimmst, dass das Host-Ergebnis gilt.
Schicht 2: TCP-Erreichbarkeit und Routing
Die Auflösung klappt; öffne jetzt eine rohe TCP-Verbindung zu jedem MQTT-Port, den du nutzen könntest:
nc -vz -w 5 broker.connectmq.com 1883 # MQTT über TCP
nc -vz -w 5 broker.connectmq.com 8883 # MQTT über TLS
nc -vz -w 5 broker.connectmq.com 8084 # MQTT über sichere WebSocketsTest-NetConnection broker.connectmq.com -Port 8883Der Unterschied zwischen einem Timeout und einer Ablehnung ist das nützlichste Signal beim Netzwerk-Debugging:
succeeded/TcpTestSucceeded : True— der Weg ist frei; weiter zu TLS.Connection refused— du hast den Host erreicht, aber dort lauscht nichts. Falscher Port oder Broker down.- Hängt und läuft dann in einen Timeout — irgendetwas zwischen dir und dem Broker verwirft die Pakete. Fast immer eine Firewall.
Um zu sehen, wo die Pakete stehen bleiben, verfolge die Route auf dem echten Port, nicht per ICMP (das viele Netze anders behandeln):
sudo traceroute -T -p 8883 broker.connectmq.com # Linux
mtr --tcp --port 8883 broker.connectmq.com # falls mtr installiert istEndet der Trace an deinem eigenen Gateway oder am ersten Firmen-Hop, ist die Sperre lokal. Endet er weit entfernt, liegt das Problem weiter vorne oder am Rand des Brokers. Eine vollständige Anleitung für Port-Checks findest du unter testen, ob ein MQTT-Port offen ist, die Standard-Ports unter MQTT-Ports.
Schicht 3: Firewalls und Proxys
Büro-, Hotel- und Cloud-Netze erlauben ausgehend oft nur HTTP(S) über einen expliziten Proxy. MQTT-Clients lesen HTTP_PROXY standardmäßig nicht, also läuft die direkte Verbindung einfach in einen Timeout.
Finde zuerst heraus, ob ein Proxy konfiguriert ist:
env | grep -i _proxy
# Windows: netsh winhttp show proxyPrüfe dann, ob der Proxy per HTTP-CONNECT einen Tunnel zum Broker-Port aufbaut:
nc -X connect -x proxy.example.corp:3128 -vz broker.connectmq.com 8883Lehnt der Proxy CONNECT auf 8883 ab, erlaubt aber 443, hast du zwei Optionen: MQTT über sichere WebSockets auf einem Port, den der Proxy zulässt, oder das Netzwerkteam bitten, den Broker-Host freizugeben. Browserbasierte Clients gehen automatisch über den System-Proxy — deshalb funktioniert der Online-MQTT-Client oft in Netzen, in denen ein nativer Client scheitert. Weitere Strategien findest du unter MQTT hinter einer Firmen-Firewall und MQTT über Port 443.
Schicht 4: TLS und Interception
Der TCP-Port ist offen, aber TLS schlägt fehl. Sieh dir das Zertifikat an, das der Client tatsächlich erhält:
openssl s_client -connect broker.connectmq.com:8883 \
-servername broker.connectmq.com -showcerts </dev/null 2>/dev/null \
| openssl x509 -noout -subject -issuer -datesVergleiche die Zeile issuer mit dem Ergebnis über einen Handy-Hotspot oder dein Heimnetz. Zeigt das Büro als Aussteller deinen Firmennamen oder einen Security-Anbieter, signiert ein TLS-inspizierender Proxy die Verbindung neu. Dein MQTT-Client lehnt sie mit certificate verify failed oder self signed certificate in certificate chain ab — und das ist korrektes Verhalten.
Lösungen, nach Präferenz geordnet:
- Bitte darum, den Broker-Host von der TLS-Inspektion auszunehmen (MQTT ist kein HTTP, und viele Inspektionsprodukte machen es ohnehin kaputt).
- Verlangt die Richtlinie Inspektion, füge die Root-CA der Firma zum Trust Store des Clients hinzu — deaktiviere niemals die Zertifikatsprüfung.
- Stelle sicher, dass der Client SNI sendet (das
-servernameoben): Ohne SNI liefern manche Endpunkte ein anderes Zertifikat, was zu Hostname-Mismatch-Fehlern führt.
Hängt der Handshake, statt fehlzuschlagen — besonders im VPN —, tippe auf ein MTU-Problem: Kleine Pakete kommen durch, die große Zertifikatsnachricht wird verworfen. Ein Test mit kleinerer MTU auf dem Interface bestätigt das. TLS-Fehler allgemein behandelt MQTT TLS handshake failed.
Die ganze Kette mit einem Skript prüfen
Dieses Skript (Python 3.8+, paho-mqtt 2.x) testet jede Schicht der Reihe nach, stoppt beim ersten Fehler und gibt die Dauer jedes Schritts aus:
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}")Ein gesunder Lauf gibt vier OK-Zeilen aus. Ein Fehler nennt dir die Schicht und die genaue Exception, die direkt zur Tabelle am Anfang dieses Artikels passt. Führe das Skript auf der Maschine aus, die das Problem hat — ein Laptop in einem anderen Netz beweist nichts über das Gerät, das scheitert.
Die Lösung bestätigen
Nachdem du DNS, Firewall-Regeln oder Proxy-Einstellungen geändert hast, prüfe Ende-zu-Ende, statt der Änderung einfach zu vertrauen:
- Führe
netcheck.pyauf der betroffenen Maschine erneut aus und bestätige, dass alle vier Schichten bestehen. - Abonniere ein Test-Topic im Online-Client und publiziere vom betroffenen Gerät darauf.
- Lass die Verbindung länger inaktiv als das vermutete Firewall-Timeout und prüfe, ob weiterhin Nachrichten ankommen.
Online-Client öffnen und Zustellung testen
Netzwerkprobleme wirken zufällig, bis du sie in Schichten zerlegst. Namen auflösen, Socket öffnen, Zertifikat prüfen, dann MQTT sprechen — der erste Schritt, der scheitert, ist der, den du reparieren musst, und die Fehlermeldung nennt ihn meist schon.
Häufig gestellte Fragen
Warum funktioniert mein MQTT-Client zu Hause, aber nicht im Büro?
Firmennetze blockieren oft ausgehende Ports wie 1883 und 8883, erzwingen einen HTTP-Proxy oder inspizieren TLS. Teste jede Schicht aus dem Büronetz: DNS, eine rohe TCP-Verbindung, den Aussteller des TLS-Zertifikats und dann MQTT. MQTT über WebSockets auf Port 443 ist häufig der Ausweg.
Wie erkenne ich, ob eine Firewall MQTT-Traffic verwirft?
Eine Firewall, die Pakete verwirft, erzeugt einen Timeout (ETIMEDOUT, 'timed out'), während ein geschlossener Port auf einem erreichbaren Host sofort mit 'Connection refused' antwortet. Führe nc -vz oder Test-NetConnection gegen den Port aus und vergleiche mit einem anderen Port desselben Hosts.
Wie erkenne ich TLS-Interception in meinem Netzwerk?
Führe openssl s_client gegen den Broker aus und gib den Zertifikatsaussteller aus. Ist der Aussteller die CA deiner Firma oder eines Security-Produkts statt einer öffentlichen CA, wird die Verbindung abgefangen, und dein Client scheitert an der Zertifikatsprüfung, solange er dieser CA nicht vertraut.

