Connecter Apache Kafka à n8n : consommer et publier des événements
Publié le 26 août 2026 · 8 min de lecture
Une plateforme Kafka ressemble souvent à une autoroute sans sortie : le cluster charrie des événements métier — commandes créées, paiements validés, alertes applicatives — mais en transformer un en action concrète suppose d'écrire un consumer Java ou Python, de le packager, de le déployer. n8n change ce rapport de forces : deux nodes natifs, Kafka pour publier et Kafka Trigger pour consommer, suffisent à brancher une automatisation métier sur un topic existant. Ce guide détaille leurs paramètres réels, la question critique des consumer groups et des offsets, et la limite de débit à connaître avant de promettre du temps réel.
Kafka n'est pas une file d'attente
C'est le malentendu fondateur, et il conditionne tout le reste. Une file RabbitMQ est un tuyau : un message y entre, un consommateur le retire, il disparaît. Un topic Kafka est un journal ordonné, partitionné et persistant : les messages y sont écrits à la suite, conservés selon une politique de rétention, et lus sans jamais être détruits. La position de lecture appartient donc au lecteur — chaque consumer group maintient un offset par partition — et le rejeu est natif. Dernier point structurant : l'ordre n'est garanti qu'au sein d'une partition.
L'étude de référence sur cette comparaison reste celle de Philippe Dobbelaere et Kyumars Sheykh Esmaili, Kafka versus RabbitMQ: A comparative study of two industry reference publish/subscribe implementations, présentée à la conférence ACM DEBS 2017 (voir sur Google Scholar). RabbitMQ y brille sur le routage riche et la faible latence message par message ; Kafka est taillé pour des flux massifs relisables depuis n'importe quel point dans le temps. Pour découpler un webhook d'un traitement lent, RabbitMQ reste le choix le plus direct ; Kafka se justifie quand le topic existe déjà et sert plusieurs consommateurs.
Créer le credential Kafka
n8n utilise un seul credential Kafka, partagé par le node producteur et le trigger. Quatre champs : Client ID, l'identifiant du client côté broker ; Brokers, la liste séparée par des virgules au format <hôte>:<port> (kafka-1:9092,kafka-2:9092) ; SSL, à laisser actif pour tout cluster distant ; et Authentication, un interrupteur qui révèle Username, Password et SASL Mechanism — trois options : Plain, scram-sha-256 et scram-sha-512.
Pour un cluster managé (Confluent Cloud, Redpanda Cloud, Aiven), la recette est presque toujours la même : SSL et Authentication activés, mécanisme Plain ou scram-sha-256 selon le fournisseur, la paire API key / API secret dans Username et Password, et le bootstrap server de la console dans Brokers — le tout chiffré comme n'importe quel autre credential (voyez le guide pour sécuriser vos identifiants API et celui des variables d'environnement). Attention enfin : il authentifie les brokers uniquement. Pour décoder de l'Avro via un Confluent Schema Registry protégé, n8n propose un credential Schema Registry distinct.
Publier dans un topic : le node Kafka
Le node Kafka n'a qu'une opération, Send message :
- Topic : le topic de destination ;
- Send Input Data : activé par défaut, il envoie tel quel le JSON de l'item courant. Désactivez-le pour reprendre la main via Message, qui accepte une expression ;
- Use Key puis Key : la clé du message. Ce n'est pas cosmétique — c'est elle qui détermine la partition, donc l'ordre relatif : publier les événements d'une même commande avec
Key = {{ $json.order_id }}garantit qu'ils atterrissent ensemble ; - Headers, des paires clé/valeur en en-tête (ou Headers (JSON) si vous activez JSON Parameters) ;
- Use Schema Registry, qui fait apparaître Schema Registry URL et Event Name — ce dernier attend le schéma sous la forme
namespace.name.
Trois options complètent le tableau : Acks (attendre l'accusé de réception de toutes les répliques), Compression (GZIP) et Timeout, à 30 000 ms par défaut.
Le cas d'usage évident : découpler un traitement lent. Le workflow déclenché par un webhook valide la requête, publie un événement et répond immédiatement ; un second consomme le topic à son rythme. Même logique que le découpage en sous-workflows, mais avec une frontière durable.
Consommer un topic : le node Kafka Trigger
Deux champs obligatoires seulement, Topic et Group ID. Le reste vit dans Options, et plusieurs valeurs par défaut méritent une lecture attentive :
- Read Messages From Beginning est activé par défaut : sur un topic à rétention longue, la première publication rejoue tout l'historique disponible ;
- JSON Parse Message convertit le corps en objet exploitable ; Only Message (visible seulement si le parsing est actif) ne renvoie que la charge utile ; Return Headers ajoute les en-têtes Kafka à la sortie ;
- Session Timeout vaut 30 000 ms et Heartbeat Interval 10 000 ms : le broker expulse du groupe un consommateur dont la session expire ;
- Max Number of Requests plafonne les requêtes non acquittées sur une connexion (1 par défaut) et Partitions Consumed Concurrently le nombre de partitions traitées en parallèle (0, soit séquentiellement) ;
- Allow Topic Creation, Auto Commit Threshold et Auto Commit Interval complètent le réglage fin.
Sans parsing, la sortie ressemble à ceci :
{
"message": "{\"order_id\":\"A-4182\",\"amount\":149.9}",
"topic": "orders.created"
}
Avec JSON Parse Message et Only Message, vous récupérez directement { "order_id": "A-4182", "amount": 149.9 } dans $json.
Consumer group et offsets : la question qui décide de tout
Le Group ID est le paramètre le plus lourd de conséquences. Kafka répartit les partitions entre les membres d'un même groupe : si deux triggers n8n partagent un Group ID, ils ne reçoivent pas le même flux, ils se partagent le flux. Un workflow de test publié avec le Group ID de production capterait silencieusement une fraction du trafic réel, en déclenchant au passage un rééquilibrage. La règle : un Group ID par usage et par environnement (n8n-crm-prod, n8n-crm-dev).
Vient ensuite la vraie question : que se passe-t-il si le workflow échoue après avoir reçu un message ? C'est le rôle du paramètre Resolve Offset, avec quatre valeurs :
- On Execution Completion (défaut) — l'offset avance à la fin de l'exécution quel que soit son statut : un workflow qui plante consomme quand même le message, et l'événement est perdu.
- On Execution Success — l'offset n'avance qu'en cas de succès. Le message sera relu, donc potentiellement traité deux fois.
- On Allowed Execution Statuses — variante fine, avec une liste Allowed Statuses (
success,error,crashed…). - Immediately — l'offset avance dès la réception. La documentation le déconseille explicitement : porte ouverte à la perte de messages.
Choisir « On Execution Success » vous place en sémantique at-least-once : aucun événement perdu, mais des doublons possibles. La réponse pratique est toujours la même : rendre le traitement idempotent. Un identifiant d'événement stocké avant l'appel coûteux, comme pour dédupliquer des webhooks rejoués, suffit à absorber le rejeu. Un Error Workflow complète le dispositif, car Kafka n'offre aucune dead letter queue native : republier les messages irrécupérables dans un topic *.dlq est à votre charge.
Le débit : n8n n'est pas un consumer haute performance
Guenter Hesse, Christoph Matthies et Matthias Uflacker, dans How Fast Can We Insert? An Empirical Performance Evaluation of Apache Kafka (IEEE ICPADS 2020 — voir sur Google Scholar), mesurent un débit d'ingestion d'environ 420 000 messages par seconde sur du matériel banalisé — sur un seul topic, une seule partition et sans réplication, donc un plafond de laboratoire plutôt qu'un chiffre de production. Un workflow n8n qui appelle un LLM en traite quelques-uns par seconde : quatre ordres de grandeur d'écart, qu'aucun réglage ne comblera.
Trois stratégies en découlent. Filtrer en amont : ne consommez pas events.all pour en jeter 99 % avec un node Filter, demandez à l'équipe data un topic « décanté » (orders.created.high_value). Multiplier les consommateurs : le mode queue de n8n avec Redis répartit les exécutions entre plusieurs workers, le parallélisme réel restant plafonné par le nombre de partitions. Accepter le décalage : sur un topic bavard, le consommateur prend du retard (lag) et ne revient jamais à niveau — mieux vaut le surveiller que le découvrir trois semaines plus tard.
Trois patterns qui fonctionnent
orders.created→ enrichissement IA → CRM : le trigger lit chaque commande, un modèle catégorise le client, un node HubSpot ou Pipedrive écrit le résultat. Volume modéré, valeur ajoutée forte : le cas idéal.- Pont vers les canaux humains : un topic d'événements techniques filtré sur la sévérité, routé vers Slack ou Teams avec un résumé généré à la volée.
- Bufferiser vers une base : le trigger écrit chaque message dans PostgreSQL et un workflow planifié agrège périodiquement. À l'inverse, n8n publie le résultat d'un traitement long — extraction de facture, transcription — sur un topic que d'autres systèmes consommeront.
Les pièges à connaître
- Le broker injoignable depuis le conteneur.
advertised.listenersmal configuré est la panne numéro un : le broker répond au bootstrap puis renvoie une adresse (localhost:9092) que le conteneur n8n ne sait pas résoudre. Dans un réseau Docker, il doit annoncer son nom de service — même famille de problème que l'erreur ECONNREFUSED sur localhost. - Read Messages From Beginning laissé par défaut. Publier le workflow rejoue alors tout l'historique : des milliers d'exécutions, des appels d'API facturés, des doublons dans le CRM.
- La compression exotique. La version 1 du Kafka Trigger lit les messages non compressés et GZIP ; elle échoue sur LZ4, Snappy et Zstd, pourtant courants côté producteurs JVM et Confluent. Il faut demander au producteur de passer en gzip, ou basculer sur la version 2 du node (en préversion à ce jour).
- Le message qui n'est pas du JSON. Un topic Avro renvoie du binaire illisible : activez Use Schema Registry et ajoutez le credential correspondant.
- La session qui expire. Un traitement plus long que Session Timeout (30 s par défaut) fait sortir le consommateur du groupe, déclenche un rééquilibrage, et le message est redistribué — donc traité deux fois.
- Allow Topic Creation activé par erreur. Une faute de frappe dans le nom du topic crée un topic vide au lieu de lever une erreur, et le workflow attend indéfiniment.
En résumé
Kafka apporte à n8n ce qu'aucune API REST ne sait donner : un flux d'événements métier persistant, relisable et déjà normalisé. Trois paramètres décident du comportement réel — le Group ID (qui partage quoi), Resolve Offset (ce qui se passe en cas d'échec) et Read Messages From Beginning (démarrage ou rejeu complet). Le reste est une question de mesure : n8n est un excellent dernier kilomètre, pas un moteur de stream processing. Filtrez en amont, rendez le traitement idempotent, surveillez le lag — et pour tout le reste, appliquez l'optimisation classique des workflows.
Pour aller plus loin
Brancher un topic Kafka sur une automatisation n'a d'intérêt que si le traitement en aval vaut le détour. Le Pack Assistant RAG (119 €) transforme un flux de documents en base de connaissance interrogeable, avec la discipline d'idempotence qui évite de ré-indexer deux fois le même événement. Pour un topic d'alertes ou de demandes entrantes, le Pack Inbox IA (79 €) fournit la brique de tri et de rédaction assistée à placer juste après le Kafka Trigger.
FAQ
Questions fréquentes
Un message Kafka est-il rejoué si le workflow n8n plante ?
Cela dépend du paramètre Resolve Offset du Kafka Trigger. Par défaut il vaut « On Execution Completion » : l'offset avance dès que l'exécution se termine, réussie ou en erreur, et le message n'est donc pas rejoué. En choisissant « On Execution Success », l'offset n'avance qu'en cas de succès et le message sera redélivré au prochain passage. Vous obtenez alors une sémantique at-least-once, qui impose de rendre le workflow idempotent : un même événement peut être traité deux fois.
Faut-il un Group ID différent entre un workflow de test et un workflow de production ?
Oui, systématiquement. Deux triggers partageant le même Group ID forment un seul consumer group : Kafka répartit les partitions entre eux et chaque message ne part que vers un seul des deux workflows. Votre instance de test « volerait » donc une partie du trafic de production, de façon silencieuse et non déterministe. Donnez un Group ID distinct par environnement (par exemple n8n-crm-prod et n8n-crm-dev) : chaque groupe possède alors ses propres offsets et reçoit l'intégralité du topic.
Combien de messages par seconde un workflow n8n peut-il consommer ?
Beaucoup moins qu'un consumer natif. Le débit d'un Kafka Trigger est celui du workflow qu'il déclenche : quelques dizaines de messages par seconde pour un traitement purement local, et souvent moins de dix par seconde dès qu'un appel LLM ou une API tierce entre en jeu. Un cluster Kafka de taille modeste encaisse plusieurs centaines de milliers d'insertions par seconde : l'écart est de plusieurs ordres de grandeur. Il faut donc filtrer en amont, consommer un topic déjà décanté, ou multiplier les workers en mode queue.
Pourquoi le Kafka Trigger échoue-t-il sur un topic Confluent ?
Deux causes dominent. D'abord la compression : la version 1 du Kafka Trigger ne décode que les messages non compressés ou en GZIP, et échoue avec une erreur de format sur LZ4, Snappy ou Zstd — des codecs courants côté producteurs JVM et Confluent. Ensuite le format : un message Avro n'est pas du JSON, il faut activer Use Schema Registry et ajouter un credential Schema Registry pour le décoder. Vérifiez aussi que le credential Kafka a bien SSL activé et l'authentification SASL renseignée.
Bundle FlowKit Complet
269 €