n8n spricht MQTT über zwei Core-Nodes: den MQTT Trigger, der Topics abonniert und für jede eingehende Nachricht einen Workflow startet, und den MQTT-Node, der aus jedem Schritt eines Workflows Nachrichten published. Leg eine MQTT-Credential mit Host, Port und Login deines Brokers an, setz einen Trigger, aktiviere den Workflow – und jeder Sensorwert kann an Slack, E-Mail, eine Datenbank, eine HTTP-API oder zurück an ein Gerät gehen.
Dieses Tutorial baut zwei echte Workflows – einen Temperaturalarm und einen Webhook-zu-Gerät-Befehl – und zeigt, wie du jeden Schritt mit einem zweiten MQTT-Client testest.
Wie n8n in ein MQTT-System passt
n8n ist ein Workflow-Automatisierungstool, kein Broker. Es verbindet sich als ganz normaler MQTT-Client mit deinem Broker:
| Rolle | n8n-Baustein | MQTT-Aktion |
|---|---|---|
| Auf Gerätedaten reagieren | MQTT Trigger | SUBSCRIBE auf einen oder mehrere Topic-Filter |
| Befehle oder abgeleitete Daten senden | MQTT-Node | PUBLISH auf ein Topic |
| Verbindungsstück | Jeder andere Node (IF, Switch, HTTP Request, Code, Slack…) | — |
Alles, was du über MQTT-Clients weißt, gilt also auch hier: Jeder Trigger braucht eine eindeutige Client-ID, QoS wird pro Subscription ausgehandelt, und die ACLs des Brokers entscheiden, was n8n lesen und schreiben darf. Wenn du schon Node-RED nutzt, ist das Modell ähnlich; als Vergleich siehe Node-RED und MQTT. Die Stärke von n8n ist die lange Liste an SaaS-Integrationen direkt neben den MQTT-Nodes.
n8n lokal starten
Am schnellsten experimentierst du mit dem offiziellen Docker-Image:
docker volume create n8n_data
docker run -it --rm --name n8n \
-p 5678:5678 \
-v n8n_data:/home/node/.n8n \
docker.n8n.io/n8nio/n8nÖffne http://localhost:5678, leg das Owner-Konto an und starte einen neuen Workflow. n8n Cloud funktioniert genauso; der einzige Unterschied: Der Broker muss aus dem Internet erreichbar sein, weil die MQTT-Verbindung von den n8n-Servern aufgebaut wird, nicht von deinem Laptop.
MQTT-Credential anlegen
Füge einen beliebigen MQTT-Node hinzu, öffne Credential to connect with und wähle Create new credential. Die MQTT-Credential hat diese wichtigen Felder:
| Feld | Wert für einen TCP-Test | Wert für TLS |
|---|---|---|
| Protocol | mqtt | mqtts |
| Host | broker.connectmq.com | broker.connectmq.com |
| Port | 1883 | 8883 |
| Username / Password | Zugangsdaten deines Brokers | Zugangsdaten deines Brokers |
| Client ID | leer lassen oder eindeutigen Wert setzen | gleich |
| Clean Session | an | an |
Nutze TLS (mqtts auf 8883) für alles, was über einen kurzen Test hinausgeht: Die Credential wird einmal gespeichert und von allen Nodes wiederverwendet – es gibt keinen Grund, Passwörter im Klartext zu senden. n8n testet die Verbindung beim Speichern; schlägt sie fehl, ist der Fehlertext meist der CONNACK-Reason des Brokers. Schlag ihn im MQTT-Reason-Code-Tool nach.
Workflow 1: Temperaturalarm
Der erste Workflow hört auf Sensorwerte und schickt eine Nachricht, wenn ein Wert einen Schwellwert überschreitet.
Schritt 1 — MQTT Trigger. Setz Topics auf testmqtt/n8n/+/temperature. Das Feld akzeptiert eine kommagetrennte Liste, und die Wildcards + und # funktionieren wie gewohnt (prüf deine Filter mit dem Topic Matcher). Aktiviere unter Options die Option JSON Parse Body, damit der Payload zu einem Objekt wird, und Only Message, falls du das Topic in späteren Schritten nicht brauchst. Behalte das Topic, wenn ein Workflow viele Geräte bedient.
Mit beiden Optionen wie gezeigt kommt eine Nachricht als Item wie dieses an:
{
"topic": "testmqtt/n8n/greenhouse-1/temperature",
"message": { "value": 31.4, "unit": "C", "ts": 1760700000 }
}Schritt 2 — IF-Node. Füge eine Bedingung hinzu: Zahl {{ $json.message.value }} ist größer als 30.
Schritt 3 — Benachrichtigen. Hänge an den true-Zweig einen Slack-, Telegram-, Discord- oder Send-Email-Node. Ein brauchbarer Nachrichtentext:
🌡 {{ $json.topic.split('/')[2] }} hat {{ $json.message.value }} °{{ $json.message.unit }}split('/')[2] holt die Geräte-ID aus dem Topic – genau deshalb lohnt sich ein konsistentes Schema; siehe Best Practices für Topic-Design.
Vor dem Aktivieren testen
Klick auf Execute workflow (oder Listen for test event am Trigger). Der Trigger wartet jetzt auf eine Nachricht. Publish einen Messwert aus dem Terminal oder aus dem Online-MQTT-Client:
mosquitto_pub -h broker.connectmq.com -p 1883 \
-t testmqtt/n8n/greenhouse-1/temperature \
-m '{"value": 31.4, "unit": "C", "ts": 1760700000}'Der Workflow läuft einmal und du kannst die Daten an jedem Node inspizieren. Publish eine zweite Nachricht mit "value": 22, um zu prüfen, dass der false-Zweig still bleibt.
Workflow 2: Webhook zu Gerätebefehl
Die Gegenrichtung ist genauso häufig: Etwas außerhalb der MQTT-Welt (ein Formular, ein Kalender, ein CRM-Event, eine andere API) soll ein Gerät schalten.
- Webhook-Node, Methode
POST, Pathlamp. Die Test-URL sieht aus wiehttp://localhost:5678/webhook-test/lamp. - IF-Node, der einen Header mit einem Shared Secret prüft, z. B. ob
{{ $json.headers['x-api-key'] }}einem in n8n hinterlegten Wert entspricht – lass nicht jeden im Internet auf deine Geräte publishen. - MQTT-Node mit Topic
testmqtt/n8n/lamp-1/set. Schalte Send Input Data aus und setz Message auf{{ $json.body.state }}. Wähle in den Optionen QoS 1 und lass Retain für momentane Befehle aus.
Mit Send Input Data an published n8n das gesamte Eingabe-Item als JSON – praktisch zum Weiterleiten, aber meist zu viel für ein Gerät, das ON oder OFF erwartet.
Beobachte das Befehls-Topic in einem Terminal und ruf den Webhook in einem anderen auf:
mosquitto_sub -h broker.connectmq.com -p 1883 -t 'testmqtt/n8n/+/set' -vcurl -X POST http://localhost:5678/webhook-test/lamp \
-H 'Content-Type: application/json' \
-H 'x-api-key: change-me' \
-d '{"state": "ON"}'Terminal 1 sollte testmqtt/n8n/lamp-1/set ON ausgeben. Für das umgekehrte Muster – MQTT-Nachrichten, die einen HTTP-Endpoint aufrufen – siehe MQTT zu Webhook.
Workflow aktivieren
Testausführungen laufen nur, solange der Editor lauscht. Um Nachrichten dauerhaft zu verarbeiten, speicherst du den Workflow und aktivierst (veröffentlichst) ihn. Ab dann hält n8n das Abonnement im Hintergrund offen, und jede Nachricht erzeugt eine Execution, die du in der Execution-Liste prüfen kannst.
Zwei Punkte zählen, sobald echter Traffic kommt:
- Anzahl der Executions. Jede Nachricht ist eine Execution. Ein Sensor, der einmal pro Sekunde published, erzeugt 86.400 Executions am Tag – das füllt die Historie und kostet CPU. Aggregiere am Edge, publish seltener oder abonniere ein „Events“-Topic statt roher Telemetrie.
- Reihenfolge. Der Trigger verarbeitet Nachrichten standardmäßig parallel. Wenn die Reihenfolge zählt (Zustandswechsel desselben Geräts), schalte die parallele Verarbeitung in den Trigger-Optionen aus, damit Nachrichten nacheinander abgearbeitet werden.
Zustellgarantien und Neustarts
n8n ist ein Client, seine Zustellgarantien sind also die des Brokers für diese Subscription:
- QoS-0-Nachrichten, die während eines n8n-Neustarts published werden, gehen verloren.
- QoS 1 mit persistenter Session (Clean Session aus und feste Client-ID) erlaubt dem Broker, Nachrichten zu puffern, während n8n down ist, und sie beim Reconnect zuzustellen. Das funktioniert nur auf einem Broker, der Sessions hält – der geteilte Test-Endpoint
broker.connectmq.comspeichert keine Offline-Sessions, also teste das gegen deine eigene private Broker-Instanz. - Retained Messages werden sofort beim Subscribe des Triggers zugestellt, ein aktivierter Workflow kann also einmal pro passendem Retained-Topic feuern. Bei State-Topics ist das meist gewollt, bei Alarm-Topics eine Überraschung; siehe Retained Messages.
Wenn du n8n im Queue Mode mit mehreren Workern betreibst, leben Trigger trotzdem auf der Main-Instanz. Starte nicht mehrere Main-Instanzen mit demselben aktiven MQTT-Workflow, sonst wird jede Nachricht mehrfach verarbeitet.
Troubleshooting-Checkliste
| Symptom | Wahrscheinliche Ursache | Lösung |
|---|---|---|
| Credential-Test scheitert mit "Not authorized" | Falscher Benutzername/Passwort oder dem User fehlt das CONNECT-Recht | Login zuerst mit mosquitto_pub/mosquitto_sub prüfen |
| Trigger verbindet sich, feuert aber nie | Topic-Filter passt nicht oder ACL verweigert Subscribe | Aus dem Online-Client auf das exakte Topic publishen; ACLs prüfen |
Expressions liefern undefined | JSON Parse Body aus, Payload ist ein String | Option aktivieren oder in einem Code-Node parsen |
| Workflow feuert zweimal pro Nachricht | Zwei aktive Workflows oder zwei n8n-Instanzen abonnieren | Duplikate deaktivieren; nur eine Main-Instanz |
| n8n Cloud kann nicht verbinden | Broker nur im LAN erreichbar | Broker mit öffentlichem Endpoint und TLS nutzen |
n8n-Topics im Browser beobachten
n8n macht aus MQTT-Nachrichten Workflows, ohne dass du einen Service schreiben musst: Ein Trigger, ein paar Nodes und ein MQTT-Publish decken die meisten Alarm- und Befehlsszenarien ab. Teste jeden Workflow mit einem zweiten Client, bevor du ihn aktivierst, gib n8n einen eigenen eingeschränkten Broker-User und halte hochfrequente Telemetrie aus den Workflows heraus, damit die Zahl der Executions im Rahmen bleibt.
Häufig gestellte Fragen
Hat n8n einen eingebauten MQTT-Node?
Ja. n8n bringt zwei Core-Nodes mit: den MQTT Trigger, der ein oder mehrere Topics abonniert und für jede Nachricht einen Workflow startet, und den MQTT-Node, der innerhalb eines Workflows eine Nachricht published. Beide nutzen dieselbe MQTT-Credential.
Warum feuert mein n8n MQTT Trigger nur, während ich teste?
Im Editor läuft 'Listen for test event' nur, solange der Editor offen ist. Für dauerhafte Verarbeitung musst du den Workflow aktivieren (veröffentlichen). Nur ein aktiver Workflow hält sein MQTT-Abonnement im Hintergrund offen.
Kann n8n JSON-Payloads aus MQTT automatisch parsen?
Ja. Aktiviere im MQTT Trigger die Option 'JSON Parse Body', dann wird das Feld message zu einem Objekt und Ausdrücke wie {{ $json.message.temperature }} funktionieren. Ohne die Option kommt der Payload als String an.



