FlowKit

Node Read/Write Files from Disk n8n : lire et écrire sur le disque

Publié le 25 août 2026 · 8 min de lecture

Un dossier déposé par un scanner, un export CSV à produire avant un transfert SFTP, un fichier de log à alimenter : ces tâches supposent qu'un workflow puisse toucher un vrai système de fichiers. Dans n8n, c'est le rôle du node Read/Write Files from Disk (n8n-nodes-base.readWriteFile). Sa particularité — et la source de presque tous les problèmes qu'on rencontre avec lui — tient en une phrase : il agit sur le disque de la machine qui exécute n8n, pas sur un stockage distant. Ce guide détaille ses deux opérations, ce que Docker change concrètement, et comment éviter les ENOENT, les EACCES et les fichiers qui disparaissent au redéploiement.

Deux opérations, un seul disque

Le node expose exactement deux opérations, sans configuration de credential puisqu'il n'y a aucune connexion à établir :

Opération Ce qu'elle fait
Read File(s) From Disk Récupère un ou plusieurs fichiers depuis la machine qui héberge n8n, et les attache comme données binaires aux items sortants
Write File to Disk Écrit un champ binaire d'un item dans un fichier, sur cette même machine

Ce « sur cette même machine » est la clé de lecture de tout le reste. Contrairement au node SFTP, Read/Write Files from Disk ne traverse pas le réseau : le chemin saisi est interprété du point de vue du process n8n. Sur un serveur nu, c'est le disque du serveur. Dans Docker — le mode d'installation majoritaire depuis notre guide d'installation — c'est le système de fichiers du conteneur, ce qui n'est pas du tout la même chose que celui de l'hôte.

Read File(s) From Disk : le motif glob change tout

Le paramètre principal s'appelle File(s) Selector. Il accepte un chemin simple (/files/rapport.pdf) mais aussi des motifs glob : * pour un segment, ** pour une descente récursive, ? pour un caractère, [] pour un ensemble. /files/entrants/*.pdf récupère tous les PDF d'un dossier ; /files/**/*.csv descend dans toute l'arborescence.

Chaque fichier trouvé produit un item, avec le contenu placé dans un champ binaire. Les Options permettent d'ajuster ce comportement :

  • Put Output File in Field — le nom du champ binaire de sortie (data par défaut). Utile quand un node en aval attend un nom précis.
  • File Name, File Extension, MIME Type — forcent les métadonnées attachées au binaire, plutôt que de laisser n8n les déduire du chemin. Indispensable quand la source produit des fichiers sans extension ou mal typés.

Le piège du glob récursif mérite d'être signalé : ** sur un dossier profond peut renvoyer des milliers d'items en une seule exécution, tous chargés d'un coup. Si le volume est incertain, restreignez le motif ou basculez le stockage binaire en mode filesystem, comme expliqué dans notre guide sur les fichiers volumineux et la mémoire de n8n — c'est le scénario qui finit en JavaScript heap out of memory.

Write File to Disk : trois paramètres, une option qui compte

Côté écriture, deux paramètres suffisent : File Path and Name, le chemin complet du fichier de destination avec son extension, et Input Binary Field, le nom du champ binaire à écrire. Le node écrit du binaire : pour produire un CSV ou un JSON, il faut donc d'abord convertir les données en fichier avec le node Convert to File, puis passer le binaire résultant à Write File to Disk.

L'unique option, Append, décide si le node écrase le fichier ou ajoute à la suite du contenu existant. C'est ce qui distingue un export régénéré à chaque exécution d'un fichier de log qui s'accumule au fil des runs. Deux réflexes évitent la majorité des échecs en écriture : utiliser un chemin absolu, et s'assurer que le dossier parent existe déjà — le node écrit un fichier, il ne construit pas une arborescence pour vous.

Cloud ou self-hosted : la vraie ligne de partage

Sur n8n Cloud, le node n'accède qu'à des chemins situés sous /home/node/, et le système de fichiers n'offre aucune garantie de persistance d'une exécution à l'autre : zone de travail éphémère, jamais stockage. Pour conserver quelque chose depuis Cloud, il faut le pousser vers S3, Drive ou SFTP.

Sur self-hosted, le node accède par défaut à ce que le process n8n peut atteindre — sa force et son risque. À noter pour les mises à jour : à partir de n8n 2.0, N8N_RESTRICT_FILE_ACCESS_TO prend ~/.n8n-files comme valeur par défaut. Un workflow qui lisait /srv/scans sans configuration particulière peut donc cesser de fonctionner après une montée de version — un cas à ajouter à la check-list de notre guide de mise à jour Docker. C'est l'un des rares points où le choix self-hosted contre Cloud est tranché d'avance : si le besoin est de lire un partage réseau, Cloud est hors jeu.

Docker : volumes, chemins et utilisateur node

Dans une installation Docker classique, un volume nommé est monté sur /home/node/.n8n pour la base SQLite et la clé de chiffrement. Ce volume ne suffit pas pour manipuler des fichiers métier : il faut monter explicitement le dossier concerné, par exemple -v /srv/scanner:/files. Dans le node, le chemin à saisir est alors /files/..., la vue du conteneur — jamais /srv/scanner/..., qui n'existe que côté hôte.

Le deuxième point de friction est l'identité du process. L'image officielle exécute n8n sous l'utilisateur node, d'UID 1000. Un dossier hôte appartenant à root sera lisible mais pas inscriptible, d'où des EACCES qui apparaissent uniquement sur l'opération d'écriture. La correction propre consiste à aligner le propriétaire côté hôte (chown -R 1000:1000 /srv/exports) plutôt qu'à passer le dossier en 777.

Le troisième point est le plus coûteux : un fichier écrit dans le conteneur, hors volume monté, disparaît au redéploiement. Le système de fichiers d'un conteneur est un empilement de couches optimisé pour la distribution, pas pour la persistance. L'étude Slacker: Fast Distribution with Lazy Docker Containers (Harter, Salmon, Liu, Arpaci-Dusseau & Arpaci-Dusseau, FAST 2016 — voir sur Google Scholar) a mesuré ce compromis sur 57 applications conteneurisées : le téléchargement des images représente 76 % du temps de démarrage d'un conteneur, alors que 6,4 % seulement de ces données sont réellement lues. Le format est taillé pour déplacer une image vite et souvent, pas pour garder vos exports au chaud. D'où la règle : tout chemin d'écriture utilisé par un workflow doit correspondre à un volume déclaré dans le docker-compose.yml, au même titre que les variables d'environnement de l'instance.

Les erreurs les plus fréquentes

Symptôme Cause probable Correctif
ENOENT en lecture Le chemin existe sur l'hôte mais pas dans le conteneur Monter le dossier en volume et saisir le chemin vu du conteneur
ENOENT en écriture Le dossier parent n'existe pas Créer le dossier en amont, ou écrire dans un chemin déjà monté
EACCES Dossier détenu par root, process en UID 1000 chown -R 1000:1000 sur le dossier hôte
Aucun item en sortie, aucune erreur Le motif glob ne correspond à rien Tester le motif, vérifier extension et casse
Le fichier écrit a disparu Écriture hors volume, conteneur recréé Écrire dans un chemin monté en volume
Le workflow marchait avant la mise à jour N8N_RESTRICT_FILE_ACCESS_TO par défaut en v2.0+ Déclarer explicitement les répertoires autorisés

Restreindre l'accès : une vraie surface de sécurité

Le node lit et écrit avec les droits du process n8n : sur une instance partagée, toute personne pouvant éditer un workflow peut lire ce que n8n peut lire. Trois garde-fous existent. N8N_RESTRICT_FILE_ACCESS_TO limite l'accès à une liste de répertoires séparés par des points-virgules ; N8N_BLOCK_FILE_ACCESS_TO_N8N_FILES, à true par défaut, bloque l'accès au dossier .n8n et aux fichiers de configuration — donc à la clé de chiffrement des credentials ; NODES_EXCLUDE permet de ne pas charger le node du tout, avec une valeur du type ["n8n-nodes-base.readWriteFile"]. Le même raisonnement vaut pour le node Execute Command.

Le danger le plus concret est la construction d'un chemin à partir d'une entrée non fiable. Un File(s) Selector du type /files/{{ $json.filename }}, alimenté par un webhook public ou un nom de pièce jointe, ouvre la porte à une traversée de répertoire : il suffit d'un ../../ bien placé pour sortir du dossier prévu. Ce n'est pas un risque théorique — l'étude Eradicating the Unseen: Detecting, Exploiting, and Remediating a Path Traversal Vulnerability across GitHub (Akhoundali, Hamidi, Rietveld & Gadyatskaya, 2025 — voir sur Google Scholar) a identifié 1 756 projets open source vulnérables à ce même motif de code, avec des scores CVSS dépassant 9,0, et seulement 14 % de correctifs appliqués après signalement. La parade dans n8n est la même que partout : ne jamais concaténer directement une entrée externe dans un chemin, valider le nom de fichier contre une liste blanche ou une expression régulière stricte dans un node Code, et cantonner l'accès à un répertoire dédié.

Quatre cas d'usage qui justifient ce node

Traiter un dossier déposé par un scanner ou un partage réseau. Un Schedule Trigger, un Read File(s) From Disk sur /files/entrants/*.pdf, puis un pipeline de classement automatique des documents entrants. C'est le scénario le plus courant, et celui où le montage de volume est incontournable.

Produire un export avant transfert. Convert to File pour générer le CSV, Write File to Disk pour le poser sur le disque, puis un node SFTP pour l'expédier. Passer par le disque permet de conserver une copie locale de ce qui a été envoyé.

Alimenter un fichier de log ou une piste d'audit. L'option Append transforme le node en journal applicatif : une ligne par exécution, dans un fichier plat que n'importe quel outil d'exploitation sait lire.

Mettre en cache un binaire volumineux hors mémoire. Écrire une archive sur le disque, la traiter par morceaux, puis la compresser ou la décompresser évite de garder plusieurs centaines de Mo dans le process pendant toute l'exécution.

Pour aller plus loin

Read/Write Files from Disk est un node simple dont toute la difficulté est ailleurs : dans la topologie de votre déploiement. Une fois les volumes et les permissions posés correctement, il devient la brique la plus fiable d'un pipeline documentaire — c'est le socle sur lequel s'appuie le tri de pièces jointes du Pack Inbox IA (79 €) quand les fichiers arrivent par un dossier partagé plutôt que par email, et celui d'une piste d'audit fichier dans le Pack Conformité & Audit (149 €), où chaque document traité laisse une trace écrite sur un volume dédié, sauvegardé avec le reste de l'instance.

FAQ

Questions fréquentes

Le node Read/Write Files from Disk fonctionne-t-il sur n8n Cloud ?

Il est présent, mais très encadré : sur n8n Cloud, le node ne peut accéder qu'à des chemins situés sous /home/node/, et le système de fichiers n'offre aucune garantie de persistance entre deux exécutions. Autrement dit, il peut servir de zone de travail temporaire à l'intérieur d'une exécution, jamais de stockage durable. Pour conserver un fichier depuis n8n Cloud, il faut l'envoyer vers un stockage externe : S3, Google Drive, SFTP.

Pourquoi mon workflow renvoie-t-il une erreur ENOENT alors que le fichier existe ?

Dans neuf cas sur dix, le chemin est correct sur la machine hôte mais pas à l'intérieur du conteneur n8n. Le node lit le système de fichiers du conteneur : si /srv/scans n'est pas monté en volume, il n'existe tout simplement pas pour n8n. Vérifiez le montage (docker inspect), utilisez le chemin tel qu'il est vu dans le conteneur, et privilégiez les chemins absolus plutôt que relatifs, dont la base dépend du répertoire de travail du process.

Comment corriger une erreur EACCES en écriture avec n8n dans Docker ?

EACCES est un problème de permissions, pas de chemin. L'image Docker officielle exécute n8n sous l'utilisateur node (UID 1000) : si le dossier monté appartient à root, l'écriture est refusée. La correction habituelle consiste à donner le dossier à l'UID 1000 côté hôte, par exemple avec chown -R 1000:1000 /srv/exports, plutôt qu'à ouvrir les droits en 777.

Comment empêcher les utilisateurs d'une instance partagée de lire n'importe quel fichier ?

Deux leviers existent. N8N_RESTRICT_FILE_ACCESS_TO limite l'accès à une liste de répertoires séparés par des points-virgules, et N8N_BLOCK_FILE_ACCESS_TO_N8N_FILES (true par défaut) bloque l'accès au dossier .n8n et aux fichiers de configuration. Si le node n'est pas nécessaire du tout, le plus simple reste de ne pas le charger via NODES_EXCLUDE, par exemple ["n8n-nodes-base.readWriteFile"].

Bundle FlowKit Complet

269 €