FlowKit

Erreur 413 dans n8n : payload trop volumineux, les 3 couches à vérifier

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

Un workflow qui marchait hier refuse un fichier aujourd'hui : 413 Request Entity Too Large, ou dans les logs PayloadTooLargeError: request entity too large. Le réflexe est immédiat — augmenter la limite. Sauf que trois couches peuvent avoir levé ce 413 : n8n lui-même, le reverse proxy posé devant lui, ou l'API distante appelée par votre node HTTP Request. La plupart des gens n'en corrigent qu'une, redémarrent, et retombent sur la même erreur.

Ce guide sert d'arbre de décision : identifier qui refuse, appliquer le bon réglage, puis traiter la cause réelle — presque toujours qu'un gros fichier n'aurait jamais dû transiter en mémoire.

Diagnostiquer avant de toucher à quoi que ce soit

Le code est le même partout, mais chaque couche le formule différemment. Lisez la réponse complète, pas seulement le code.

  • Le node HTTP Request échoue avec un 413 : c'est le serveur distant qui refuse, aucun réglage local n'y changera rien.
  • Un Webhook, un formulaire, un import de workflow ou un upload échoue : c'est votre pile — n8n ou le proxy.
  • La réponse est une page HTML titrée « 413 Request Entity Too Large » : c'est nginx (ou un autre proxy), n8n ne produit pas de HTML pour ses erreurs d'API.
  • La réponse est un JSON mentionnant PayloadTooLargeError : c'est n8n, via le middleware de parsing d'Express.

Un test en ligne de commande tranche :

# Fabriquer un fichier de 20 Mo et l'envoyer au webhook
head -c 20000000 /dev/urandom > /tmp/test.bin
curl -v -X POST https://n8n.exemple.fr/webhook-test/mon-hook \
  -F "file=@/tmp/test.bin" 2>&1 | tail -30

Répétez avec 500 Ko, 5 Mo, 50 Mo : le seuil de bascule désigne le coupable. Un blocage net à 1 Mo pointe nginx, à 16 Mo pointe n8n. Si rien n'apparaît dans les logs du conteneur, la requête n'y est jamais arrivée — la méthode du débogage de workflow, appliquée à la couche réseau.

Ce flou n'a rien d'anecdotique. Dans « An Empirical Study on Configuration Errors in Commercial and Open Source Systems » (SOSP 2011), Zuoning Yin, Xiao Ma et leurs coauteurs analysent 546 erreurs de configuration réelles : seules 7,2 % à 15,5 % produisent un message désignant explicitement le paramètre en cause (voir sur Google Scholar). Le 413 en est un cas d'école : un code correct qui ne dit jamais quel plafond a sauté, ni où.

Couche 1 — n8n et N8N_PAYLOAD_SIZE_MAX

n8n limite lui-même la taille des corps qu'il accepte, sur ses webhooks comme sur son API interne. La variable N8N_PAYLOAD_SIZE_MAX s'exprime en MiB et vaut 16 par défaut. La documentation précise que l'instance doit être redémarrée pour que le changement s'applique, et qu'un plafond plus élevé consomme plus de mémoire et de CPU.

# docker-compose.yml
services:
  n8n:
    image: docker.n8n.io/n8nio/n8n
    restart: unless-stopped
    environment:
      - N8N_PAYLOAD_SIZE_MAX=128
      - N8N_FORMDATA_FILE_SIZE_MAX=200
      - N8N_DEFAULT_BINARY_DATA_MODE=filesystem
    volumes:
      - n8n_data:/home/node/.n8n

Une seconde variable, souvent ignorée : N8N_FORMDATA_FILE_SIZE_MAX, qui fixe en MiB la taille maximale des fichiers dans les payloads webhook form-data, avec 200 par défaut. Elle ne se substitue pas à la première : un envoi multipart/form-data doit passer les deux contrôles, et c'est pourquoi un upload de 60 Mo échoue alors que la limite form-data est à 200 — N8N_PAYLOAD_SIZE_MAX, resté à 16, a tranché. Les deux appartiennent au groupe Endpoints du référentiel des variables d'environnement.

En mode queue avec Redis, la variable doit être réglée à l'identique sur le main et sur tous les workers, faute de quoi les échecs semblent aléatoires selon le worker qui a pris la tâche. Et si votre webhook reçoit un fichier en base64 dans le body, souvenez-vous que l'encodage gonfle la taille d'un tiers : un PDF de 12 Mo dépasse alors 16 Mo. La même limite frappe l'import de workflows volumineux.

Couche 2 — le reverse proxy, cause numéro un

Le suspect le plus fréquent : ses valeurs par défaut sont bien plus basses que celles de n8n.

nginx

client_max_body_size vaut 1 Mo par défaut : tout upload sérieux est refusé avant d'atteindre n8n. La directive se place dans un bloc http, server ou location :

server {
    listen 443 ssl;
    server_name n8n.exemple.fr;

    client_max_body_size 100M;
    client_body_timeout 300s;

    location / {
        proxy_pass http://127.0.0.1:5678;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_read_timeout 300s;
        proxy_request_buffering off;
    }
}

proxy_request_buffering off fait passer le corps en flux plutôt que de l'écrire d'abord sur disque. Rechargez avec nginx -t && nginx -s reload, en vérifiant qu'aucun autre bloc ne réintroduit une valeur plus basse (guide nginx devant n8n).

Traefik

Traefik n'impose pas de limite par défaut, mais si vous utilisez le middleware buffering, c'est maxRequestBodyBytes qui décide, en octets. memRequestBodyBytes (1 048 576 par défaut) est le seuil de bascule sur disque.

# labels Docker sur le service n8n
labels:
  - "traefik.enable=true"
  - "traefik.http.routers.n8n.rule=Host(`n8n.exemple.fr`)"
  - "traefik.http.services.n8n.loadbalancer.server.port=5678"
  - "traefik.http.middlewares.n8n-body.buffering.maxRequestBodyBytes=104857600"
  - "traefik.http.middlewares.n8n-body.buffering.memRequestBodyBytes=2097152"
  - "traefik.http.routers.n8n.middlewares=n8n-body"

La dernière ligne est essentielle : un middleware déclaré mais jamais attaché au routeur ne s'applique à rien.

Caddy

Caddy n'applique pas de plafond tant que vous n'en déclarez pas un, via request_body :

n8n.exemple.fr {
    request_body {
        max_size 100MB
    }
    reverse_proxy 127.0.0.1:5678
}

Au-delà de max_size, Caddy renvoie lui aussi un 413. Ces deux proxys sont détaillés dans le guide HTTPS et nom de domaine.

Cloudflare

Si votre domaine est proxifié (nuage orange), Cloudflare applique sa propre limite de corps de requête, dépendante du plan : 100 Mo sur Free et Pro, 200 Mo sur Business, 500 Mo par défaut sur Enterprise — ce dernier plafond étant relevable auprès du support. Au-delà, Cloudflare renvoie un 413 et la requête n'atteint jamais votre serveur. Aucun réglage local n'y change rien : changer de plan, sortir l'upload du proxy, ou ne plus faire transiter le fichier.

Couche 3 — c'est l'API distante qui refuse

Quand le 413 apparaît dans la sortie d'un node HTTP Request, le problème est chez le destinataire : vous ne configurez pas son serveur, il n'y a rien à augmenter. Trois parades :

  • Découper l'envoi : au lieu d'un POST de 5 000 enregistrements, des lots de 200 avec un node Loop Over Items — beaucoup d'API documentent une taille de lot maximale ;
  • Utiliser l'upload multipart ou chunké prévu par l'API : la plupart des services de stockage exposent un upload en plusieurs parties, précisément pour ne jamais dépasser une taille de requête ;
  • Envoyer une URL plutôt que le fichier, ce qui fait retomber le payload à quelques centaines d'octets.

Un 413 distant n'est jamais transitoire : inutile de le rejouer, réservez les tentatives aux erreurs qui le méritent (retry et timeouts du node HTTP Request).

Le vrai correctif : ne plus faire transiter les fichiers en mémoire

Relever les plafonds fait disparaître le symptôme ; la cause est architecturale. Par défaut, n8n conserve les données binaires en mémoire — c'est ce que signifie la valeur default de N8N_DEFAULT_BINARY_DATA_MODE. La passer à filesystem écrit les binaires sur disque, dans le chemin N8N_BINARY_DATA_STORAGE_PATH, et allège d'autant la heap de Node.js. Les modes s3 et azure, réservés aux offres Enterprise, déportent le stockage (comparatif des modes).

Corollaire : les données binaires ne devraient jamais finir dans le JSON. Un fichier en base64 dans un champ devient de la donnée JSON ordinaire, sérialisée puis stockée dans la base d'exécutions.

Le plus efficace reste le pattern d'URL signée : le client ne pousse pas le fichier vers n8n, il obtient une URL de dépôt signée, écrit directement sur S3 ou GCS, puis appelle le webhook avec un simple lien. Aucune limite n'est franchie — le raisonnement de l'archivage de fichiers sur S3.

Déplacer ainsi le problème vers l'amont rejoint la littérature sur les configurations « latentes ». Dans « Early Detection of Configuration Errors to Reduce Failure Damage » (OSDI 2016), Tianyin Xu, Xinxin Jin et leurs coauteurs montrent que les paramètres qui ne servent pas à l'initialisation — ceux qui ne jouent qu'en cas de panne, de bascule ou de pic — ne sont souvent validés par aucun code au démarrage, et restent donc « latents » jusqu'au jour où leur mauvaise valeur provoque un dégât coûteux (voir sur Google Scholar). Un client_max_body_size laissé par défaut en est le cas parfait : il ne gêne personne pendant six mois, puis casse la production au premier gros fichier.

Les erreurs cousines à ne pas confondre

  • JavaScript heap out of memory : la requête est passée, mais son traitement a saturé la mémoire de Node.js — souvent la conséquence d'un N8N_PAYLOAD_SIZE_MAX relevé sans discernement (diagnostic complet) ;
  • 504 Gateway Timeout : la taille passe, mais le transfert dépasse le délai du proxy. Symptôme d'un proxy_read_timeout trop court, pas d'un plafond de taille ;
  • Les payloads qui passent mais font enfler la base : aucune erreur, mais la table des exécutions grossit de plusieurs gigaoctets par semaine — à traiter par une purge régulière des exécutions.

Les pièges

  • Régler la variable dans le mauvais conteneur : dans une stack à plusieurs services n8n (main, worker, webhook), la poser sur un seul ne protège que celui-là ;
  • Oublier de redémarrer : la variable est lue au démarrage, et un docker compose up -d sans recréation du conteneur ne suffit pas toujours. Vérifiez avec docker exec n8n printenv | grep PAYLOAD ;
  • Mettre la variable sous command au lieu de environment : elle n'est jamais exportée, le conteneur démarre normalement et le réglage reste sans effet ;
  • Confondre MiB et octets : n8n attend des MiB (128), Traefik des octets (134217728), nginx des suffixes (100M) ;
  • Corriger une seule couche : nginx relevé à 100 Mo, n8n laissé à 16 — l'erreur change de forme mais reste ;
  • Augmenter au lieu de traiter la cause : chaque requête acceptée est bufferisée en mémoire, et si la donnée finit en JSON, elle grossit la base d'exécutions. Passer de 16 à 512 MiB, c'est accepter que quelques exécutions concurrentes fassent tomber l'instance.

La check-list, dans l'ordre

  1. Proxy : client_max_body_size (nginx), middleware buffering (Traefik), request_body (Caddy), plan Cloudflare — la cause n°1 ;
  2. n8n : N8N_PAYLOAD_SIZE_MAX et, en form-data, N8N_FORMDATA_FILE_SIZE_MAX, sur tous les process, puis redémarrage ;
  3. Mode binaire : N8N_DEFAULT_BINARY_DATA_MODE=filesystem, et bannir le base64 dans le JSON ;
  4. API distante : si le 413 vient d'un node HTTP Request, découper, passer en multipart, ou envoyer une URL.

Avancez point par point, en retestant après chaque changement : c'est le seul moyen de savoir ce qui a vraiment corrigé le problème, et de ne pas laisser trois limites relevées pour rien.

Pour aller plus loin

Les erreurs 413 frappent surtout les workflows qui manipulent des documents : pièces jointes, factures, contrats, exports. Le Pack Inbox IA (79 €) traite les pièces jointes via les propriétés binaires plutôt que du base64 en JSON, ce qui évite d'y arriver. Pour l'ingestion documentaire à volume, le Pack Assistant RAG (119 €) applique le même principe : le fichier reste sur son stockage, le workflow ne fait circuler que des références.

FAQ

Questions fréquentes

Comment augmenter la taille maximale de payload dans n8n ?

En définissant la variable d'environnement N8N_PAYLOAD_SIZE_MAX, exprimée en MiB, dont la valeur par défaut est 16. Par exemple N8N_PAYLOAD_SIZE_MAX=128 autorise des corps de requête jusqu'à 128 MiB. Le changement n'est pris en compte qu'après redémarrage du process, et en mode queue il doit être appliqué à l'identique sur le main et sur tous les workers. Attention : la documentation n8n précise elle-même qu'un payload plus gros consomme davantage de mémoire et de CPU.

Pourquoi mon webhook n8n renvoie 413 alors que N8N_PAYLOAD_SIZE_MAX est déjà augmenté ?

Parce que le refus vient d'une couche située devant n8n. La cause la plus fréquente est nginx, dont la directive client_max_body_size vaut 1 Mo par défaut : la requête est rejetée avant même d'atteindre n8n. Vérifiez le corps de la réponse — une page HTML nginx signe le proxy, un JSON avec PayloadTooLargeError signe n8n. Traefik, Caddy et Cloudflare ont chacun leur propre plafond à contrôler.

Quelle est la limite d'upload de Cloudflare devant une instance n8n ?

Elle dépend du plan Cloudflare, pas de n8n : 100 Mo sur les plans Free et Pro, 200 Mo sur Business, 500 Mo par défaut sur Enterprise, ce dernier étant relevable sur demande auprès du support. Au-delà, Cloudflare renvoie lui-même un 413 et la requête n'atteint jamais votre serveur. Aucune variable d'environnement n8n ne contourne ce plafond : il faut soit changer de plan, soit sortir le trafic d'upload du proxy, soit ne plus faire transiter le fichier.

Faut-il augmenter la limite ou changer d'architecture ?

Augmenter la limite est un correctif de dépannage : chaque requête acceptée est intégralement bufferisée, ce qui pèse sur la RAM de l'instance et, si les données finissent en JSON, gonfle la base d'exécutions. Le correctif structurel consiste à ne plus faire transiter le fichier : passer N8N_DEFAULT_BINARY_DATA_MODE en filesystem pour sortir les binaires de la mémoire, et adopter le pattern d'URL signée où le client dépose sur S3 et n'envoie au webhook qu'un lien de quelques centaines d'octets.

Bundle FlowKit Complet

269 €