Rien ne crie « j’aime les délais » comme une équipe marketing qui tente d’uploader une vidéo principale de 120 MB cinq minutes avant le lancement — pour finalement recevoir le message « exceeds the maximum upload size for this site » ou le classique « exceeds upload_max_filesize ».
Cette erreur n’est jamais due à un seul réglage. C’est une chaîne. PHP impose des limites. Le serveur web impose des limites. Les proxys et CDN ont des limites. WordPress a ses règles. Votre panneau d’hébergement a des valeurs par défaut « utiles ». La bonne correction consiste à trouver le maillon le plus faible, l’augmenter intentionnellement et vérifier ce qui a réellement changé.
Mode d’intervention rapide
Si vous ne faites rien d’autre, faites ceci. Ça transforme « j’ai modifié php.ini et rien n’a changé » en un ticket court et ennuyeux. L’ennui, c’est bien.
1) Identifier la surface d’erreur réelle : message WordPress, statut HTTP ou log serveur
- Si le navigateur affiche HTTP 413 ou une page Nginx/Cloudflare standard : vous êtes bloqué avant PHP. Corrigez d’abord le proxy/serveur web.
- Si WordPress affiche « exceeds upload_max_filesize » ou « exceeds the maximum upload size » : vous atteignez probablement les limites PHP (ou WordPress lit les limites PHP et les affiche).
- Si ça tourne puis échoue avec « link expired » / « failed to write file to disk » / « missing a temporary folder » : ce n’est pas une limite de taille ; c’est le système de fichiers, le répertoire tmp ou les permissions.
2) Trouver la plus petite limite dans la chaîne
Les uploads échouent à la valeur minimale de :
- Quirks du navigateur/client (rare, mais le mobile peut timeout)
- Limite du corps de requête CDN/WAF/proxy
- Limite du corps de requête du serveur web (Nginx/Apache)
- Limites SAPI PHP :
upload_max_filesize,post_max_size,memory_limit, timeouts - Contraintes disque : espace libre, partition tmp, épuisement des inodes
- WordPress + plugins (moins fréquent, mais réel)
3) Vérifier ce que PHP utilise réellement (ne pas deviner)
PHP peut charger différents fichiers ini selon la SAPI (FPM vs CLI), le pool et le packaging de la distribution. Confirmez le fichier chargé et les valeurs effectives.
4) Modifier une couche à la fois et redémarrer le bon service
Redémarrer le mauvais démon est un rite d’initiation. C’est aussi une perte de temps. Changez la bonne configuration, validez la syntaxe, reload/restart, puis testez.
5) Retester avec une taille d’upload qui devrait échouer, puis une qui devrait passer
Tester avec un fichier de 2 MB après avoir « augmenté à 512 MB » ne vous dit rien. Choisissez un fichier à 50–80 % de la nouvelle limite, puis réessayez.
Une citation à garder dans votre runbook : Espérer n’est pas une stratégie.
(General H. Norman Schwarzkopf)
Ce que signifie réellement l’erreur (et ce qu’elle ne signifie pas)
« exceeds upload_max_filesize » est PHP qui parle — spécifiquement le sous-système d’upload de fichiers. Ce message est lancé quand PHP refuse d’accepter un fichier parce qu’il est plus volumineux que upload_max_filesize. WordPress affiche généralement cela comme un message convivial dans l’interface de la médiathèque.
Mais la réalité en production est désordonnée. Vous pouvez voir ce message même si :
- Votre proxy bloque le corps de la requête et WordPress devine la limite d’après les paramètres PHP (vous augmentez PHP, WordPress affiche un plus grand chiffre, mais les uploads échouent toujours à la périphérie).
- Vous avez édité le mauvais
php.ini(fréquent sur les hébergements multi-PHP, conteneurs, ou quand CLI != FPM). post_max_sizeest encore plus petit queupload_max_filesize(votre fichier est dansupload_max_filesize, mais le corps POST complet ne l’est pas).- Vous atteignez des timeouts (uploads volumineux sur des liens lents), pas des plafonds de taille.
Notez aussi : l’erreur ne dit rien sur le disque. Vous pouvez augmenter les limites à 2 GB et échouer parce que /tmp est petit ou le volume est plein. Les uploads de fichiers ne sont pas magiques ; ils atterrissent quelque part.
La chaîne des limites d’upload : où les uploads sont bloqués
Pensez à un upload WordPress comme un colis qui passe des contrôles. N’importe quel contrôle peut le refuser. Votre travail est de trouver quel garde l’arrête.
Point de contrôle A : CDN/WAF/reverse proxy
Si vous avez Cloudflare, un WAF géré, un ALB/ELB, une API gateway ou un contrôleur d’entrée Nginx, vous avez probablement un plafond sur la taille de la requête et parfois un comportement de buffering qui change la manière dont les gros uploads se comportent.
Point de contrôle B : Serveur web
Nginx a par défaut une limite de corps de requête relativement petite dans de nombreuses configurations (client_max_body_size). Apache peut aussi appliquer une taille via des directives comme LimitRequestBody (bien que ce ne soit pas toujours défini par défaut).
Point de contrôle C : SAPI PHP (FPM/mod_php)
La trilogie classique :
upload_max_filesize: plafond par fichier.post_max_size: plafond du corps POST total (doit être plus grand queupload_max_filesize; prévoyez une marge).memory_limit: affecte le traitement et certains plugins ; il n’est pas toujours nécessaire qu’il soit plus grand que la taille du fichier, mais pratiquement vous voulez de la marge.
Surveillez aussi :
max_execution_time,max_input_time: timeouts pour uploads lents et traitements PHP.max_file_uploads: nombre de fichiers par requête (rarement un problème WordPress, mais des plugins de bulk upload peuvent l’atteindre).upload_tmp_dir: emplacement des fichiers temporaires PHP ; s’il pointe vers un petit filesystem, vous perdez.
Point de contrôle D : Système de fichiers et OS
Les uploads écrivent sur l’espace temporaire, puis dans wp-content/uploads (ou où que ce soit configuré). Modes d’échec :
- Disque plein ou épuisement des inodes
- Permissions/ownership incorrects
- Les flags de montage
noexecn’affectent généralement pas les médias, mais les politiques SELinux/AppArmor peuvent - Le stockage overlay d’un conteneur qui se remplit alors que le volume attaché a de l’espace
Point de contrôle E : WordPress et plugins
WordPress affiche « Taille maximale d’upload » basé sur ce que PHP lui dit. Les plugins peuvent ajouter leurs propres validations, et certains plugins de sécurité bloquent certains types MIME ou extensions, que les utilisateurs interprètent parfois à tort comme une erreur de « taille ».
Faits intéressants & petite histoire des limites d’upload
- La limite d’upload par défaut de PHP était volontairement petite. Des valeurs par défaut comme 2 MB étaient courantes parce que l’hébergement mutualisé des années 2000 était une lutte pour les ressources.
post_max_sizecompte même pour un upload d’un seul fichier. Le fichier fait partie d’un formulaire multipart ; le corps complet inclut des délimiteurs et champs, il faut donc de la marge.- Nginx rejette les corps trop gros tôt. Quand
client_max_body_sizeest dépassé, Nginx peut retourner 413 sans jamais toucher PHP-FPM. C’est protecteur pour le backend, déroutant pour les humains. - « 413 Request Entity Too Large » est plus ancien que la plupart des sites WordPress. C’est un statut HTTP issu d’une époque où « entity » était utilisé dans les specs pour la charge utile de la requête.
- WordPress ne « définit » pas les limites PHP. Il les lit. Tout réglage dans le tableau de bord qui prétend changer PHP écrit des fichiers de configuration ou ment poliment.
- PHP-FPM et PHP CLI sont des SAPIs différentes. Le CLI peut vous montrer des valeurs plausibles tandis que FPM utilise d’autres ini. Beaucoup d’incidents commencent quand quelqu’un lance
php -iet s’y fie. - Les uploads écrivent souvent d’abord sur le stockage temporaire. PHP écrit sur un fichier temporaire avant de le déplacer. Si
/tmpest sur une petite partition, les gros uploads échouent même si le volume final a de l’espace. - Les CDN limitent souvent la taille des requêtes sur les plans d’entrée de gamme. Vous pouvez augmenter Nginx et PHP autant que vous voulez et bloquer à la périphérie. La périphérie ne négocie pas.
- Les gros uploads média ne sont devenus la norme que récemment. Les téléphones modernes filment en 4K par défaut ; des « clips rapides » de 200 MB sont maintenant courants et vont anéantir des defaults à 2 MB avec enthousiasme.
Tâches pratiques : commandes, sorties, décisions (12+)
Voici les opérations que j’attends d’un SRE sur un hôte réel. Chaque tâche inclut : la commande, ce que la sortie signifie et la décision à prendre.
Task 1: Confirm the effective PHP limits (CLI sanity check)
cr0x@server:~$ php -r 'echo "upload_max_filesize=",ini_get("upload_max_filesize"),"\npost_max_size=",ini_get("post_max_size"),"\nmemory_limit=",ini_get("memory_limit"),"\n";'
upload_max_filesize=2M
post_max_size=8M
memory_limit=128M
Ce que ça signifie : C’est la vue PHP CLI. Elle peut ne pas correspondre à PHP-FPM ou mod_php.
Décision : Si le CLI est déjà élevé mais que WordPress échoue toujours, arrêtez d’éditer des ini au hasard et vérifiez la SAPI web ensuite.
Task 2: Identify which PHP SAPI you’re running (FPM vs Apache module)
cr0x@server:~$ ps -ef | egrep 'php-fpm|apache2|httpd' | head
root 1012 1 0 09:00 ? 00:00:02 php-fpm: master process (/etc/php/8.2/fpm/php-fpm.conf)
www-data 1044 1012 0 09:00 ? 00:00:00 php-fpm: pool www
root 1200 1 0 09:00 ? 00:00:01 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
Ce que ça signifie : Vous êtes sur Nginx + PHP-FPM. Les modifications doivent cibler la configuration FPM/pool, pas Apache.
Décision : Passez aux emplacements de configuration FPM et reload PHP-FPM et Nginx.
Task 3: Find the loaded php.ini for PHP-FPM (not CLI)
cr0x@server:~$ php-fpm8.2 -i | egrep 'Loaded Configuration File|Scan this dir for additional .ini files'
Loaded Configuration File => /etc/php/8.2/fpm/php.ini
Scan this dir for additional .ini files => /etc/php/8.2/fpm/conf.d
Ce que ça signifie : C’est le fichier ini et le répertoire scanné pour la SAPI FPM.
Décision : Éditez /etc/php/8.2/fpm/php.ini ou créez un override dédié dans conf.d, puis reload PHP-FPM.
Task 4: Check the effective values in the FPM ini file
cr0x@server:~$ sudo egrep -n '^(upload_max_filesize|post_max_size|memory_limit|max_execution_time|max_input_time)' /etc/php/8.2/fpm/php.ini
861:upload_max_filesize = 2M
701:post_max_size = 8M
436:memory_limit = 128M
409:max_execution_time = 30
415:max_input_time = 60
Ce que ça signifie : Ce sont les valeurs configurées actuelles pour FPM.
Décision : Augmentez-les selon vos besoins d’uploads, puis reload PHP-FPM. Assurez-vous aussi que post_max_size soit supérieur à upload_max_filesize.
Task 5: Check Nginx request body limit across the config
cr0x@server:~$ sudo nginx -T 2>/dev/null | egrep -n 'client_max_body_size'
45: client_max_body_size 1m;
212: client_max_body_size 16m;
Ce que ça signifie : Vous avez plusieurs scopes. Le bloc le plus spécifique l’emporte.
Décision : Définissez client_max_body_size là où votre vhost WordPress correspond réellement (généralement dans le bloc server). Supprimez les valeurs contradictoires si possible.
Task 6: Validate Nginx config before reloading
cr0x@server:~$ sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
Ce que ça signifie : Sûr de recharger. Si la syntaxe échoue, ne reload pas ; corrigez le fichier d’abord.
Décision : Reload Nginx seulement après un -t propre.
Task 7: Reload services correctly (and verify they actually reloaded)
cr0x@server:~$ sudo systemctl reload nginx
cr0x@server:~$ sudo systemctl reload php8.2-fpm
cr0x@server:~$ systemctl is-active nginx php8.2-fpm
active
active
Ce que ça signifie : Le reload a réussi et les services sont toujours actifs.
Décision : Si le reload échoue ou qu’un service n’est pas actif, stoppez — corrigez le service avant de tester les uploads.
Task 8: Inspect PHP-FPM pool overrides (they can silently cap values)
cr0x@server:~$ sudo egrep -n 'php_admin_value\[(upload_max_filesize|post_max_size|memory_limit)\]|request_terminate_timeout' /etc/php/8.2/fpm/pool.d/www.conf
;php_admin_value[upload_max_filesize] = 10M
;php_admin_value[post_max_size] = 12M
;request_terminate_timeout = 0
Ce que ça signifie : Commenté ici, mais sur certains systèmes ces directives sont actives et écrasent php.ini.
Décision : Si des overrides de pool existent, définissez-y des valeurs intentionnellement, documentez-les, et arrêtez de prétendre que php.ini est toujours souverain.
Task 9: Check Apache body size directives (if you run Apache)
cr0x@server:~$ sudo apachectl -M | head -n 5
Loaded Modules:
core_module (static)
so_module (static)
watchdog_module (static)
http_module (static)
Ce que ça signifie : Apache est présent ; si c’est votre frontend, vérifiez les limites Apache et l’intégration PHP (mod_php ou proxy_fcgi).
Décision : Si vous êtes sur Apache, recherchez LimitRequestBody et vérifiez votre vhost.
Task 10: Search Apache config for request size limits
cr0x@server:~$ sudo grep -R --line-number -E 'LimitRequestBody' /etc/apache2/sites-enabled /etc/apache2/apache2.conf 2>/dev/null
/etc/apache2/sites-enabled/000-default.conf:27:LimitRequestBody 10485760
Ce que ça signifie : Apache est limité à 10 MB sur ce vhost. Les changements PHP ne suffiront pas.
Décision : Augmentez LimitRequestBody (ou retirez-le si vous gérez les limites ailleurs), puis reload Apache.
Task 11: Confirm disk space and inode availability (uploads need both)
cr0x@server:~$ df -h /var/www/html /tmp
Filesystem Size Used Avail Use% Mounted on
/dev/vda1 80G 62G 15G 81% /
tmpfs 1.0G 120M 904M 12% /tmp
cr0x@server:~$ df -i /var/www/html /tmp
Filesystem Inodes IUsed IFree IUse% Mounted on
/dev/vda1 5242880 910000 4332880 18% /
tmpfs 262144 980 261164 1% /tmp
Ce que ça signifie : Vous avez 15 GB libres et les inodes vont bien. /tmp fait 1 GB, ce qui peut être juste pour de gros uploads.
Décision : Si vous voulez autoriser des uploads à 2 GB, agrandissez le stockage temporaire ou définissez upload_tmp_dir vers un filesystem plus grand.
Task 12: Check WordPress’s reported max upload size (what the admin sees)
cr0x@server:~$ sudo -u www-data php /var/www/html/wp-admin/includes/file.php 2>/dev/null || true
Ce que ça signifie : Ce n’est pas une excellente méthode pour interroger WordPress, mais ça rappelle : WordPress est du code PHP. La valeur affichée côté admin est dérivée des paramètres PHP, pas l’inverse.
Décision : Utilisez un phpinfo() côté web si besoin (voir la tâche suivante), puis supprimez-le.
Task 13: Create a temporary phpinfo page to confirm FPM values (then delete it)
cr0x@server:~$ sudo tee /var/www/html/phpinfo.php >/dev/null <<'EOF'
/etc/php/8.2/fpm/php.ini
Ce que ça signifie : Vous inspectez maintenant PHP tel que servi par la stack web, ce qui importe réellement.
Décision : Confirmez les valeurs ; puis supprimez phpinfo.php. Le laisser traîner est une invitation aux ennuis.
Task 14: Inspect logs for 413 or PHP upload errors
cr0x@server:~$ sudo tail -n 50 /var/log/nginx/error.log
2025/12/27 09:22:18 [error] 1432#1432: *991 client intended to send too large body: 24681231 bytes, client: 203.0.113.9, server: example.com, request: "POST /wp-admin/async-upload.php HTTP/1.1", host: "example.com", referrer: "https://example.com/wp-admin/media-new.php"
Ce que ça signifie : Ce n’est pas PHP. Nginx rejette le corps de la requête (ici ~24.6 MB).
Décision : Augmentez client_max_body_size dans le scope approprié. Ne touchez pas PHP tant que Nginx reste le contrôleur.
Task 15: Validate PHP error log for upload-specific failures
cr0x@server:~$ sudo tail -n 50 /var/log/php8.2-fpm.log
[27-Dec-2025 09:25:10] WARNING: [pool www] child 2123 said into stderr: "PHP message: PHP Warning: POST Content-Length of 52459012 bytes exceeds the limit of 8388608 bytes in Unknown on line 0"
Ce que ça signifie : post_max_size est à 8 MB (8388608 bytes). L’utilisateur a tenté ~52 MB. PHP l’a rejeté avant que WordPress ne puisse agir.
Décision : Augmentez post_max_size au-dessus de la taille d’upload désirée, avec marge.
Task 16: Confirm a proxy/CDN isn’t enforcing a smaller cap (example: Cloudflare via response headers)
cr0x@server:~$ curl -I -sS https://example.com/wp-admin/media-new.php | egrep -i 'server:|cf-ray|via:|x-cache'
server: cloudflare
cf-ray: 88f0c1d2ab123456-LHR
Ce que ça signifie : Cloudflare est dans le chemin. Les limites d’upload peuvent dépendre du plan et se manifester par des erreurs 413/520.
Décision : Si vous voyez une implication de la périphérie, reproduisez en contournant celle-ci (test direct sur l’origine) ou vérifiez les paramètres de taille au niveau de la périphérie. Ne supposez pas que l’origine est le problème.
Blague 1 : Les limites d’upload ressemblent aux politiques de frais en entreprise — tout le monde les découvre seulement quand il essaie de faire quelque chose de normal.
Corriger selon la stack : Apache, Nginx, PHP-FPM, proxys, panels, conteneurs
Choisir des limites sensées (et arrêter de dire « mets à 2G » comme plan)
Commencez par un besoin réel : « Nous avons besoin d’uploader des vidéos jusqu’à 200 MB » ou « Nous avons besoin de 64 MB pour des PDFs ». Ensuite définissez :
upload_max_filesize= besoin (ex. 256M)post_max_size= upload_max_filesize + overhead (ex. 300M)memory_limit= dépend des plugins et du traitement d’images ; pour WP riche en médias, 256M–512M est courant- Limite corps serveur/proxy = au moins
post_max_size
Si vous autorisez de très gros uploads, planifiez aussi la bande passante, les timeouts et la croissance du stockage. « Les uploads fonctionnent » n’est pas synonyme de « les uploads ne feront pas fondre le serveur le mois prochain ».
Nginx + PHP-FPM (configuration moderne la plus courante)
1) Augmenter client_max_body_size dans Nginx
Définissez-le dans le bloc server approprié (ou dans http pour global). Extrait de vhost :
cr0x@server:~$ sudo tee /etc/nginx/sites-available/example.com.conf >/dev/null <<'EOF'
server {
listen 80;
server_name example.com;
root /var/www/html;
client_max_body_size 300m;
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
}
}
EOF
Décision : Réglez Nginx au moins à post_max_size. Si Nginx est plus bas que PHP, les utilisateurs recevront 413 ; si PHP est plus bas que Nginx, les utilisateurs auront des erreurs PHP/WordPress. Dans tous les cas, vous recevrez un ticket.
2) Augmenter les limites PHP-FPM dans le bon ini
Éditez l’ini FPM ou déposez un fichier d’override propre dans conf.d (plus propre pour la gestion de configuration).
cr0x@server:~$ sudo tee /etc/php/8.2/fpm/conf.d/99-wordpress-uploads.ini >/dev/null <<'EOF'
upload_max_filesize = 256M
post_max_size = 300M
memory_limit = 512M
max_execution_time = 120
max_input_time = 120
EOF
Décision : Utilisez un override clairement nommé. Ça facilite les audits et la réponse aux incidents plutôt que d’explorer un php.ini fourni par un vendor.
3) Reload, puis vérifier via phpinfo côté web
Reload FPM et Nginx. Confirmez dans le phpinfo servi que les nouvelles valeurs sont actives. Ensuite supprimez phpinfo.
Configurations Apache
Apache peut exécuter PHP via mod_php (ancienne méthode) ou via PHP-FPM (proxy_fcgi). Les limites diffèrent selon l’intégration.
Plafonds du corps de requête Apache
Si vous avez LimitRequestBody dans votre vhost ou contexte directory, c’est un plafond dur. Augmentez-le (en octets) ou retirez-le si vous contrôlez les limites ailleurs.
cr0x@server:~$ sudo sed -i 's/LimitRequestBody 10485760/LimitRequestBody 314572800/' /etc/apache2/sites-enabled/000-default.conf
cr0x@server:~$ sudo apachectl configtest
Syntax OK
cr0x@server:~$ sudo systemctl reload apache2
Décision : Si vous utilisez Apache comme reverse proxy devant FPM, alignez la taille d’Apache avec le post_max_size de PHP.
Limites PHP (mod_php vs FPM)
Si vous exécutez mod_php, le chemin ini est généralement /etc/php/X.Y/apache2/php.ini. Si vous utilisez FPM, c’est /etc/php/X.Y/fpm/php.ini. Ne « corrigez » pas l’ini Apache si Apache ne sert pas PHP directement.
Reverse proxies et load balancers
Coupables fréquents :
- Nginx devant Nginx (oui, vraiment). Chaque couche peut avoir son propre
client_max_body_size. - Ingress controllers Kubernetes avec leurs propres réglages de corps de requête.
- Règles WAF qui bloquent de gros corps ou certains patterns multipart.
La méthode est la même : trouvez la couche qui émet 413 (ou qui reset la connexion), puis augmentez cette couche. Si vous pouvez bypasser le proxy temporairement (accès direct à l’origine), faites-le pour restreindre le diagnostic.
cPanel / Plesk / panneaux d’hébergement gérés
Les panneaux offrent souvent des boutons « augmenter la taille d’upload ». Sous le capot ils modifient des ini ou des configs par site. Le piège est la configuration en double :
- Le panneau écrit dans un ini, mais votre site utilise une version PHP différente ou un handler différent.
- Le panneau augmente PHP, mais Nginx/Apache limite toujours le corps.
- Les changements du panneau sont écrasés par des mises à jour ou votre gestion de configuration.
Utilisez le panneau si c’est le modèle de gouvernance, mais vérifiez toujours avec phpinfo et les logs. Les panneaux sont une UI, pas une vérité absolue.
Docker et WordPress conteneurisé
Les conteneurs ajoutent deux irrégularités classiques :
- Vous pouvez éditer un fichier de configuration sur l’hôte que le conteneur n’utilise pas.
- Le proxy frontal (Traefik/Nginx/Ingress) a souvent le vrai plafond, pas le conteneur PHP.
Si vous exécutez l’image officielle WordPress avec Apache, ajustez PHP via des snippets ini montés dans le conteneur.
cr0x@server:~$ docker exec -it wordpress php -i | egrep 'Loaded Configuration File|upload_max_filesize|post_max_size' | head
Loaded Configuration File => /usr/local/etc/php/php.ini
upload_max_filesize => 2M => 2M
post_max_size => 8M => 8M
Décision : Si le conteneur montre encore 2M/8M, vous devez monter un override ini dans /usr/local/etc/php/conf.d (ou rebuild l’image), puis redémarrer le conteneur.
Contraintes côté WordPress : ce qui compte, ce qui est cargo cult
Le message WordPress « Taille maximale d’upload » est un affichage symptomatique
Dans Média → Ajouter, WordPress affiche une taille maximale. Ce chiffre est généralement dérivé de upload_max_filesize et post_max_size de PHP, parfois avec de la logique additionnelle. Ce n’est pas une garantie que tout le chemin supporte cette taille.
« Hacks » dans wp-config.php
Vous verrez des conseils pour ajouter des constantes ou des appels ini_set dans wp-config.php :
ini_set('upload_max_filesize','256M')define('WP_MEMORY_LIMIT','256M')
La vérité : ini_set() ne peut pas changer les paramètres PHP_INI_SYSTEM dans de nombreuses configurations, et php_admin_value des pools FPM peut le bloquer entièrement. Si ça marche, c’est fragile. Si ça ne marche pas, des gens perdent des journées en croyant que WordPress les ignore par malveillance.
Privilégiez l’approche ennuyeuse et exécutable : fixez les limites PHP dans les ini/pool, fixez les limites serveur web dans la config du serveur, vérifiez dans les logs.
Le memory_limit n’est pas une limite d’upload (mais peut quand même tuer les uploads)
Uploader un fichier ne requiert pas que PHP garde tout le fichier en mémoire ; il le stream vers un fichier temporaire. Mais les plugins peuvent traiter les fichiers (redimensionnement d’images, extraction de métadonnées vidéo, aperçus PDF) et consommer la mémoire. Si vous augmentez les limites d’upload et voyez ensuite des écrans blancs ou des erreurs fatales après l’upload, c’est souvent la mémoire ou le temps d’exécution durant le traitement, pas l’upload lui-même.
Les blocages MIME et extensions déguisés en « erreurs d’upload »
Certains hébergeurs bloquent certaines extensions. WordPress a aussi des restrictions MIME pour les uploads. Quand un utilisateur entend « upload failed », il suppose la taille. Vérifiez le message réel et les logs. Un SVG, EXE ou un conteneur vidéo exotique bloqué n’est pas un problème de taille.
Blague 2 : « Juste augmenter la limite » est l’équivalent opérationnel de « avez-vous essayé d’éteindre puis rallumer ? » — parfois correct, toujours suspect.
Erreurs courantes (symptôme → cause racine → fix)
1) Symptom: WordPress says max upload is 256MB, but uploads fail with HTTP 413
Cause racine : Limite du corps de requête Nginx/proxy en amont plus basse que PHP.
Fix : Augmentez client_max_body_size (et tout plafond proxy en amont). Confirmez dans le log Nginx que vous ne voyez plus « client intended to send too large body ».
2) Symptom: You edited php.ini, restarted PHP, nothing changed
Cause racine : Vous avez édité le mauvais ini (CLI vs FPM vs Apache), ou un override de pool le surpasse.
Fix : Vérifiez le fichier de configuration chargé pour la SAPI web avec phpinfo ; recherchez php_admin_value dans les configs de pool.
3) Symptom: Upload fails at ~8MB or ~16MB exactly, regardless of settings
Cause racine : Plafond d’un dispositif en amont (WAF, ALB, ingress controller), ou LimitRequestBody d’Apache.
Fix : Identifiez la couche qui renvoie 413 via logs et headers ; augmentez ce plafond. Ne montez pas aveuglément PHP en premier.
4) Symptom: Upload starts, then fails with “The link you followed has expired.”
Cause racine : Souvent des timeouts ou une expiration de nonce durant des uploads lents ; parfois max_execution_time ou des timeouts proxy.
Fix : Augmentez les timeouts PHP et les timeouts de lecture proxy ; assurez-vous que l’utilisateur n’uploade pas via un lien si lent qu’il dépasse les timeouts du serveur.
5) Symptom: Upload fails with “Missing a temporary folder” or “Failed to write file to disk”
Cause racine : upload_tmp_dir mal configuré, permissions incorrectes, disque plein, ou /tmp trop petit.
Fix : Vérifiez df -h, df -i, permissions sur /tmp et wp-content/uploads, et définissez upload_tmp_dir sur un chemin writable avec de l’espace.
6) Symptom: Only large images fail; small images succeed
Cause racine : Le traitement d’images après upload atteint memory_limit ou max_execution_time ; ou un plugin effectue un traitement coûteux.
Fix : Augmentez memory_limit, profilez le comportement des plugins, envisagez de déporter le redimensionnement d’images ou de limiter les tailles auto-générées.
7) Symptom: Works when bypassing CDN, fails through CDN
Cause racine : Plafond de taille au niveau de l’edge ou règle WAF bloquant multipart/form-data.
Fix : Ajustez les paramètres CDN/WAF, ou routez les uploads admin/media directement vers l’origine si votre architecture le permet.
Listes de contrôle / plan étape par étape
Étapes : augmenter les limites en toute sécurité sur Nginx + PHP-FPM
- Choisir une taille cible d’upload. Exemple : 256M. Décidez
post_max_size=300M. - Vérifier les bloqueurs actuels : log Nginx pour 413 ; log PHP-FPM pour « POST Content-Length exceeds ».
- Définir la limite Nginx dans le vhost approprié :
client_max_body_size 300m; - Définir l’override PHP-FPM :
upload_max_filesize,post_max_size, timeouts, et éventuellementmemory_limit. - Valider et reload :
nginx -t, reload Nginx et PHP-FPM. - Vérifier via phpinfo côté web (temporairement) puis supprimer.
- Tester les uploads à 50–80 % de la limite et juste au-delà pour confirmer le comportement d’échec.
- Surveiller le disque : Assurez-vous que
/tmpet votre volume WordPress peuvent gérer les uploads concurrents. - Documenter les nouvelles limites dans un runbook, incluant où elles sont configurées.
Checklist : ce qu’il faut aligner entre les couches (correction minimale)
client_max_body_size(ou équivalent Apache) ≥post_max_sizepost_max_size≥upload_max_filesize+ overhead- Capacité du stockage temporaire ≥ upload maximum (× concurrence prévue)
- Timeouts PHP et timeouts proxy cohérents avec les durées d’upload
- Paramètres origine, proxy et CDN cohérents (pas de plafond caché plus bas)
Checklist : garde-fous opérationnels (pour que « augmenter les limites » ne devienne pas « oups »)
- Décidez si vous voulez permettre de gros uploads seulement côté admin (certaines stacks peuvent scoper les limites par location).
- Ajoutez du monitoring : utilisation disque, utilisation des inodes, et taux d’erreurs 413 et warnings d’upload PHP.
- Gardez un plan de rollback : revert du snippet ini, revert de la directive vhost, reload des services.
- Si vous autorisez de très gros uploads, envisagez d’externaliser les médias vers du object storage et d’utiliser des uploads multipart.
Trois mini-histoires du monde corporate
Mini-histoire 1 : L’incident causé par une fausse hypothèse
Une entreprise retail utilisait WordPress comme « CMS léger » derrière une couche de reverse proxy. Un jour, l’équipe produit a lancé une nouvelle landing page avec de courtes vidéos. Les uploads ont commencé à échouer de manière intermittente, surtout pour le personnel à distance. L’ingénieur on-call a vu l’erreur WordPress concernant upload_max_filesize, a édité /etc/php/8.1/fpm/php.ini, augmenté les limites, rechargé PHP-FPM et déclaré victoire.
Le prochain upload a encore échoué. Même message. Ils ont augmenté encore, car si 256M ne marchait pas, 512M marcherait sûrement. Ce ne fut pas le cas. Maintenant l’équipe avait deux problèmes : les uploads échouaient toujours, et PHP était configuré pour accepter des payloads plus gros sans aucune discussion sur le disque, les timeouts ou la résistance aux abus.
La cause racine était douloureusement banale : le reverse proxy avait client_max_body_size à 20M. WordPress affichait la nouvelle limite PHP plus élevée, mais le proxy bloquait à 20M. Les utilisateurs proches du siège réussissaient parfois parce que leurs fichiers étaient plus petits ; les personnes distantes uploadaient des assets plus gros.
La correction prit dix minutes : augmenter la limite proxy pour qu’elle corresponde à post_max_size, recharger, et ajouter une alerte log sur les réponses 413. La leçon réelle prit plus de temps : ne pas supposer que le message d’erreur pointe la couche fautive. Dans un système multi-couches, le premier composant qui rejette la requête écrit la vérité, et WordPress n’est généralement pas ce composant.
Mini-histoire 2 : L’optimisation qui s’est retournée contre eux
Un site lourd en médias décida « d’optimiser les performances » en resserrant les limites partout. Ils passèrent client_max_body_size de Nginx à 10M parce que « personne ne devrait uploader plus que ça » et cela réduisit un peu le bruit des bots. Ils baissèrent aussi les timeouts PHP parce que les requêtes longues étaient jugées suspectes.
Puis l’entreprise organisa des webinars. Le marketing eut soudainement des vignettes de 80M pour des vidéos (ne demandez pas) et des uploads audio de 150M. Le personnel contourna le problème en utilisant FTP puis en déplaçant manuellement les fichiers dans wp-content/uploads, ce qui contourna la génération de métadonnées WordPress et cassa la médiathèque. Bien pour la disponibilité, catastrophique pour la cohérence.
Le vrai retour de bâton fut opérationnel : le contournement augmenta les étapes manuelles et créa un état incohérent. Certains fichiers existaient sur le disque mais pas dans la base. Certains étaient référencés par des URLs qui n’avaient jamais été régénérées après un changement de domaine. Quand ils relevèrent finalement les limites, ils héritèrent d’un tas de « médias fantômes » et d’un problème de confiance : les utilisateurs ne croyaient plus que le système d’upload fonctionnait, même quand c’était le cas.
La solution finale ne fut pas « ouvrir les vannes ». Ils définirent une politique claire (256M), alignèrent les limites entre l’edge, le proxy et PHP, et ajoutèrent ensuite un offload média dédié. Optimiser, oui. Optimiser sans comprendre les workflows, voilà comment on se retrouve avec un système rapide qui ne sait pas faire le travail.
Mini-histoire 3 : La pratique ennuyeuse mais correcte qui a sauvé la mise
Un intranet corporate important hébergeait plusieurs instances WordPress sur la même flotte. Rien d’excitant. L’équipe plateforme gardait un petit ensemble de defaults durcis, incluant des limites d’upload. Mais ils appliquaient aussi une règle : tout changement de limite doit être fait via un unique snippet de configuration déployé par l’automatisation, et vérifié par un health check qui lit les valeurs effectives.
Quand un nouveau site demanda des uploads de vidéos de formation plus gros, l’équipe ne toucha pas php.ini directement. Ils ajoutèrent un seul fichier ini dans conf.d, relevèrent les réglages vhost Nginx, et mirent à jour un canary check qui uploadait un fichier légèrement en dessous de la limite sur une instance staging. Puis ils déployèrent progressivement.
Deux semaines plus tard, une mise à jour de l’image de base remplaça le php.ini vendor. Les sites qui avaient édité ce fichier à la main seraient revenus à 2M et auraient déclenché une alarme helpdesk. Cette flotte ne fut pas affectée. Le snippet d’override survécut, le canary continua de passer, et personne ne le remarqua.
C’est ce que l’ennui achète : l’immunité contre le type de changement qui ruine un vendredi soir. Les gens aiment les fixes malins. La production aime les fixes reproductibles.
FAQ
1) Quelle est la différence entre upload_max_filesize et post_max_size ?
upload_max_filesize limite un seul fichier uploadé. post_max_size limite le corps HTTP POST entier. Pour les uploads de fichiers, le corps POST est toujours plus gros que le fichier à cause de l’overhead multipart. Mettez post_max_size plus haut.
2) J’ai augmenté upload_max_filesize mais WordPress affiche toujours l’ancienne limite. Pourquoi ?
Soit vous avez modifié le mauvais ini PHP (CLI vs FPM vs Apache), soit le changement n’a pas été rechargé, soit une autre config (override de pool FPM php_admin_value) le surpasse. Confirmez avec un phpinfo côté web.
3) Pourquoi j’ai HTTP 413 au lieu d’une erreur WordPress ?
Parce que quelque chose devant WordPress a rejeté le corps de la requête avant que PHP ne le voie — souvent client_max_body_size de Nginx, LimitRequestBody d’Apache, un load balancer ou un CDN.
4) Dois-je augmenter memory_limit pour qu’il corresponde à la taille de l’upload ?
Pas strictement pour le transfert lui-même, mais souvent pour ce qui suit : redimensionnement d’images, extraction de métadonnées, aperçus PDF, traitement par des plugins. Si les uploads réussissent mais que le traitement échoue, la mémoire est suspecte.
5) À quelle hauteur dois-je fixer les limites d’upload pour WordPress ?
Fixez-les à la plus petite valeur qui couvre les besoins réels avec de la marge. Pour beaucoup de sites, 64M–256M est pratique. Si vous avez besoin de plus, envisagez un offload média vers un object storage et revoyez les timeouts et la capacité disque.
6) Puis-je définir les limites dans .htaccess ?
Parfois, sur Apache avec mod_php, des directives comme php_value upload_max_filesize dans .htaccess peuvent fonctionner. Avec PHP-FPM, elles ne fonctionneront généralement pas. Considérez la tuning .htaccess comme legacy et vérifiez les résultats.
7) Pourquoi les uploads échouent seulement pour certains utilisateurs ou réseaux ?
Des uplinks lents peuvent atteindre les timeouts. Des proxies d’entreprise peuvent interférer. Aussi, les utilisateurs peuvent uploader des fichiers différents. Vérifiez les timeouts, vérifiez si les protections edge varient par région, et testez depuis le réseau d’origine.
8) Augmenter les limites d’upload est-ce un risque de sécurité ?
Ça peut l’être. Des corps plus grands exposent plus de ressources : bande passante, disque temporaire, CPU pour le traitement et des requêtes plus longues. Définissez les limites intentionnellement, scindez-les si possible (chemins admin), et monitorisez.
9) Comment savoir quelle couche bloque l’upload ?
Cherchez 413 dans le navigateur et dans les logs Nginx/Apache. Si Nginx logge « client intended to send too large body », c’est Nginx. Si PHP logge « POST Content-Length exceeds », c’est PHP. Sinon, suspectez CDN/WAF ou des problèmes de système de fichiers.
10) Pourquoi ça marchait hier et échoue aujourd’hui sans changement ?
Raisons courantes : une mise à jour de package a remplacé des configs, un panneau a réinitialisé des réglages, le disque s’est rempli, ou une politique proxy/WAF a changé. C’est pourquoi les snippets de configuration + les vérifications sont utiles.
Conclusion : prochaines étapes sans mauvaises surprises
Corriger « exceeds upload_max_filesize » n’est pas trouver la ligne magique dans php.ini. Il s’agit d’aligner les limites sur tout le chemin de la requête et de prouver la configuration effective côté web.
Faites ceci ensuite :
- Exécutez le mode d’intervention rapide et identifiez si le bloqueur est à la périphérie, au serveur web ou côté PHP.
- Fixez une taille cible claire et alignez
client_max_body_size/LimitRequestBody,post_max_sizeetupload_max_filesize. - Reload les bons services, puis vérifiez via phpinfo servi (brièvement) et les logs.
- Vérifiez le disque et l’espace temporaire. Si vous autorisez de gros uploads, planifiez la concurrence et la croissance.
- Notez où vivent les réglages. Le vous du futur est un inconnu ; laissez-lui une carte.