Un instant votre site WordPress est opérationnel. L’instant suivant, c’est un rectangle blanc vide : aucun contenu, aucune erreur affichée, aucune information. Les clients pensent que vous avez été piraté. Le marketing pense « Internet est en panne ». Vous fixez le vide, ce qui est peut-être pire qu’une erreur 500, car au moins une 500 reconnaît qu’elle est cassée.
Ceci est l’Écran blanc de la mort (WSOD). Ce n’est généralement pas mystique. Il s’agit presque toujours d’une erreur fatale PHP, d’une exhaustion de mémoire, ou d’un cache/couche edge qui renvoie une réponse vide. L’astuce consiste à arrêter de deviner et à suivre une séquence stricte qui force la défaillance à se révéler.
Playbook de diagnostic rapide (quoi vérifier en premier)
Si vous êtes de garde, fatigué et que votre Slack ressemble à une scène de crime, utilisez ceci. C’est optimisé pour obtenir un signal rapidement. L’objectif est d’identifier la couche en panne : edge/cache, serveur web, runtime PHP, base de données ou code WordPress (plugins/thèmes).
Premièrement : est-ce vraiment l’origine (origin) ?
- Vérifiez depuis votre portable en contournant le cache. Si un CDN ou reverse proxy sert une réponse vide en cache, vous poursuivrez des fantômes sur le serveur.
- Interrogez l’origine directement (hosts file, IP directe avec Host header, ou DNS du load balancer interne) pour isoler les problèmes d’edge.
Deuxièmement : problème HTTP ou problème PHP ?
- Regardez le statut HTTP et les en-têtes. Un 200 avec un corps de 0 octet est souvent PHP qui meurt après avoir envoyé les en-têtes, un comportement bizarre d’output buffering, ou un cache qui renvoie un objet vide.
- Surveillez les logs web + PHP. Vous cherchez une ligne d’erreur fatale avec un horodatage correspondant à la requête blanche.
Troisièmement : forcez WordPress à s’accuser
- Enable WP_DEBUG + debug.log (avec prudence) et reproduisez une fois.
- Disable plugins en masse (renommer le répertoire ou WP-CLI) puis retestez.
- Switch to a default theme et retestez.
Quatrièmement : les choses peu glamours
- Mémoire/limites : memory_limit PHP, max_execution_time, opcache, permissions des fichiers, disque plein.
- Modifications récentes : mises à jour, nouveau plugin, nouveau thème, changement de version PHP, exécution d’un outil de gestion de configuration, modification de la politique de purge de cache.
Ceci est le playbook. Maintenant faisons le travail avec une séquence en cinq étapes qui produit des réponses, pas des impressions.
Ce qu’est réellement le WSOD (et pourquoi il trompe)
Le WSOD n’est pas un bug unique. C’est un symptôme : votre requête s’est terminée sans rendre de sortie visible. Cela peut arriver pour plusieurs raisons :
- Erreur fatale PHP avant l’affichage (ou l’affichage est supprimé). Souvent causée par du code de plugin/thème incompatible, des classes manquantes, ou l’appel d’une fonction supprimée dans une version plus récente de PHP.
- Exhaustion de mémoire (classique) : « Allowed memory size exhausted ». Parfois vous ne le verrez pas dans le navigateur car display_errors est désactivé.
- Bizarreries d’output buffering/caching : une couche de cache stocke une réponse vide et la sert comme « réussie ».
- Échecs de permissions ou du système de fichiers : WordPress ne peut pas lire des fichiers de thème, ne peut pas écrire le cache, ne peut pas autoloader quelque chose ; le runtime meurt.
- Problèmes de cache d’opcode (moins courant aujourd’hui, mais réel) : opcache obsolète après des déploiements ou modèles d’invalidation cassés.
- Problèmes d’Edge/CDN : pas du tout WordPress. La « page blanche » est un placeholder d’une couche intermédiaire.
Le WSOD trompe parce que les navigateurs sont polis. Ils ne hurlent pas sur le corps vide ; ils n’affichent simplement rien. Votre serveur, cependant, a hurlé — dans les logs, dans stderr, dans le journal systemd — quelque part. Votre travail est de trouver où le cri est allé.
Une citation à garder en tête pendant les incidents :
« L’espoir n’est pas une stratégie. » — Gene Kranz
Cela résume l’opération en cinq mots : arrêtez d’espérer que « c’est juste un problème de cache » et commencez à prouver quelle couche échoue.
Blague #1 : L’Écran blanc de la mort est le seul moment où une page blanche compte comme « transparence totale ».
La réparation en 5 étapes qui fonctionne
Étape 1 : Confirmer le mode de défaillance (code de statut, taille du corps, implication du cache)
Avant de toucher à WordPress, confirmez ce que les clients reçoivent réellement. Si l’edge sert une réponse vide en cache, vous réparerez l’origine et verrez toujours du blanc jusqu’à l’expiration du cache.
À faire : capturez les en-têtes, le code de statut, la longueur du contenu et les en-têtes de cache. Comparez l’origine vs le CDN.
À éviter : éditer immédiatement wp-config.php sur un pressentiment. En production, les pressentiments sont la façon de créer un second incident.
Étape 2 : Lire les logs sérieusement (web + PHP-FPM + journal système)
Le WSOD est généralement une erreur fatale PHP. Les erreurs fatales atterrissent dans les logs PHP-FPM, les logs d’erreur du serveur web, ou le journal système selon la configuration de votre stack.
À faire : tail des logs tout en reproduisant le problème une fois. La corrélation temporelle vaut mieux que l’archéologie.
À éviter : lire des logs d’il y a trois jours pendant que vos checks de load balancer frappent de nouvelles erreurs chaque seconde.
Étape 3 : Activer la journalisation de debug WordPress (sans transformer votre site en confessionnal)
WordPress peut enregistrer les notices/warnings/fatals PHP dans wp-content/debug.log. C’est souvent la source la plus propre pour les échecs de plugin/thème.
À faire : activer la journalisation, désactiver l’affichage dans le navigateur, reproduire, puis la désactiver.
À éviter : activer display_errors sur un site public. Les équipes sécurité ont aussi des sentiments.
Étape 4 : Réduire la complexité rapidement (désactiver tous les plugins, changer de thème)
La plupart des WSOD sont auto-infligés par du code exécuté à l’intérieur de WordPress. Les plugins et thèmes sont du code non fiable avec une belle interface. Traitez-les en conséquence.
À faire : désactivez les plugins en masse (renommer le répertoire plugins ou utiliser WP-CLI). Ensuite, basculez sur un thème par défaut (Twenty Twenty-*). Retestez après chaque changement.
À éviter : désactiver les plugins un par un via wp-admin quand wp-admin lui-même est blanc. Ce n’est pas du dépannage ; c’est une performance.
Étape 5 : Corriger la contrainte sous-jacente (mémoire, version PHP, permissions, stockage, base de données)
Une fois que vous connaissez le déclencheur — incompatibilité de plugin, extension PHP manquante, exhaustion de mémoire, disque plein — appliquez la vraie correction. Si c’est la mémoire, augmentez-la correctement et confirmez ; si c’est un mauvais déploiement, revenez en arrière ; si c’est le disque, libérez de l’espace et empêchez la récurrence. Récupérer n’est pas la même chose que prévenir.
Passons maintenant aux commandes concrètes. Pas « essayez d’éteindre et de rallumer ». Des tâches réelles, des sorties réelles, des décisions réelles.
Tâches pratiques : commandes, sorties et décisions (12+)
Hypothèses pour les exemples ci-dessous :
- Serveur Linux avec Nginx + PHP-FPM (nous mentionnerons aussi Apache).
- WordPress se trouve dans
/var/www/wordpress. - Vous avez SSH et sudo.
Task 1: Check HTTP status, headers, and body size (from a shell)
cr0x@server:~$ curl -sS -D - -o /dev/null -w "status=%{http_code} bytes=%{size_download} time=%{time_total}\n" https://example.com/
HTTP/2 200
date: Tue, 04 Feb 2026 10:12:01 GMT
content-type: text/html; charset=UTF-8
cache-control: max-age=0, must-revalidate
cf-cache-status: HIT
status=200 bytes=0 time=0.092
Ce que cela signifie : HTTP 200 mais bytes=0. De plus, un en-tête de cache indique que le CDN l’a servi (HIT).
Décision : contournez le cache / interrogez l’origine directement. Ne touchez pas encore à WordPress ; vous regardez peut-être une réponse cache vide.
Task 2: Bypass cache and compare response
cr0x@server:~$ curl -sS -H "Cache-Control: no-cache" -D - -o /dev/null -w "status=%{http_code} bytes=%{size_download}\n" https://example.com/
HTTP/2 500
date: Tue, 04 Feb 2026 10:12:11 GMT
content-type: text/html; charset=UTF-8
status=500 bytes=0
Ce que cela signifie : Le contournement du cache révèle un 500 à l’origine (ou au moins non caché). Bien : vous chassez maintenant une erreur réelle.
Décision : Allez immédiatement consulter les logs et reproduisez une fois.
Task 3: Tail Nginx error log while reproducing
cr0x@server:~$ sudo tail -n 50 -f /var/log/nginx/error.log
2026/02/04 10:12:11 [error] 13219#13219: *918 FastCGI sent in stderr: "PHP message: PHP Fatal error: Uncaught Error: Call to undefined function get_field() in /var/www/wordpress/wp-content/themes/custom/functions.php:211" while reading response header from upstream, client: 203.0.113.15, server: example.com, request: "GET / HTTP/2.0", upstream: "fastcgi://unix:/run/php/php8.2-fpm.sock:", host: "example.com"
Ce que cela signifie : Le thème appelle get_field() (Advanced Custom Fields) mais la fonction n’existe pas — plugin manquant/désactivé, ou chargé trop tard.
Décision : Désactivez le thème ou restaurez le plugin manquant. Ce n’est pas un problème de base de données. C’est du code.
Task 4: Tail PHP-FPM log (or systemd journal) for fatals
cr0x@server:~$ sudo tail -n 50 -f /var/log/php8.2-fpm.log
[04-Feb-2026 10:12:11] WARNING: [pool www] child 22109 said into stderr: "PHP Fatal error: Uncaught Error: Call to undefined function get_field() in /var/www/wordpress/wp-content/themes/custom/functions.php:211"
Ce que cela signifie : Confirme que le fatal provient du runtime PHP. Vous avez maintenant le fichier et le numéro de ligne.
Décision : Procédez à l’isolation thème/plugin (Étape 4) et/ou restaurez la modification de thème.
Task 5: Check disk space (blank pages sometimes mean “disk full”)
cr0x@server:~$ df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sda1 80G 79G 200M 100% /
tmpfs 3.8G 2.0M 3.8G 1% /run
Ce que cela signifie : Le système de fichiers root est plein. PHP peut échouer à écrire des sessions, des fichiers de cache ou des logs ; WordPress peut échouer à mettre à jour des options autoloadées ; tout devient étrange.
Décision : Libérez de l’espace maintenant (logs, anciennes releases, cache), puis mettez en place rotation/monitoring. Ne « augmentez pas la mémoire » pour un problème de disque.
Task 6: Find what’s consuming space quickly
cr0x@server:~$ sudo du -xhd1 /var | sort -h
120M /var/cache
1.8G /var/lib
6.5G /var/log
14G /var/www
Ce que cela signifie : Les logs sont énormes. C’est soit un trafic élevé, soit une boucle de logging, soit une absence de rotation.
Décision : Inspectez /var/log et effectuez une rotation/troncature en toute sécurité (et corrigez la cause racine).
Task 7: Identify top log offenders
cr0x@server:~$ sudo find /var/log -type f -printf "%s %p\n" | sort -n | tail -n 10
2147483648 /var/log/nginx/access.log
1073741824 /var/log/nginx/error.log
536870912 /var/log/php8.2-fpm.log
Ce que cela signifie : Vos logs gonflent. Peut-être une tempête de bots, peut-être une boucle de redirection, peut-être le logging de debug activé par erreur.
Décision : Tronquez pour récupérer de l’espace (court terme), puis corrigez logrotate et les erreurs bruyantes (long terme).
Task 8: Safe-ish truncation to recover space fast
cr0x@server:~$ sudo sh -c ': > /var/log/nginx/error.log; : > /var/log/php8.2-fpm.log'
Ce que cela signifie : Les fichiers sont tronqués in situ (les processus gardent les handles). Cela donne un peu d’air sans redémarrer les services.
Décision : Vérifiez immédiatement df -h. Ensuite, mettez en place la rotation. Et demandez-vous pourquoi error.log faisait 1 Go : ce n’est pas « normal ».
Task 9: Enable WordPress debug logging (controlled)
Éditez wp-config.php et définissez ces valeurs près du bas, au-dessus de « That’s all » :
cr0x@server:~$ sudo sed -n '1,120p' /var/www/wordpress/wp-config.php
<?php
/* ...existing config... */
define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);
define('WP_DEBUG_DISPLAY', false);
/* That's all, stop editing! Happy publishing. */
Ce que cela signifie : Les erreurs vont dans wp-content/debug.log, pas dans le navigateur.
Décision : Reproduisez le WSOD une fois, puis lisez le debug.log. Désactivez ensuite cette journalisation.
Task 10: Read the WordPress debug log
cr0x@server:~$ sudo tail -n 60 /var/www/wordpress/wp-content/debug.log
[04-Feb-2026 10:12:11 UTC] PHP Fatal error: Uncaught Error: Call to undefined function get_field() in /var/www/wordpress/wp-content/themes/custom/functions.php:211
Stack trace:
#0 /var/www/wordpress/wp-settings.php(595): include()
#1 /var/www/wordpress/wp-config.php(95): require_once('...')
#2 /var/www/wordpress/wp-load.php(50): require_once('...')
#3 /var/www/wordpress/wp-blog-header.php(13): require_once('...')
#4 /var/www/wordpress/index.php(17): require('...')
#5 {main}
thrown in /var/www/wordpress/wp-content/themes/custom/functions.php on line 211
Ce que cela signifie : Confirme le fatal au niveau du thème, fonction de plugin manquante. La stack trace montre que cela meurt pendant le bootstrap.
Décision : Corrigez la dépendance du thème ou restaurez le plugin requis. Récupération la plus rapide : basculer vers le thème par défaut.
Task 11: Disable all plugins via filesystem rename (works even when wp-admin is dead)
cr0x@server:~$ cd /var/www/wordpress/wp-content
cr0x@server:~$ sudo mv plugins plugins.disabled
cr0x@server:~$ ls -l
drwxr-xr-x 2 www-data www-data 4096 Feb 4 10:13 plugins.disabled
drwxr-xr-x 10 www-data www-data 4096 Feb 4 09:50 themes
Ce que cela signifie : WordPress ne trouvera pas les plugins ; il les traitera comme désactivés.
Décision : Retestez le site. S’il revient, vous avez prouvé une défaillance liée à un plugin. Réactivez ensuite sélectivement (renommez, ou activez un par un avec WP-CLI).
Task 12: Switch theme without wp-admin (rename current theme folder)
cr0x@server:~$ cd /var/www/wordpress/wp-content/themes
cr0x@server:~$ sudo mv custom custom.disabled
cr0x@server:~$ ls -1
custom.disabled
twentytwentyfour
twentytwentythree
Ce que cela signifie : WordPress basculera sur un thème par défaut disponible.
Décision : Si le site se charge maintenant, votre thème est en faute. Gardez le thème par défaut temporairement ; corrigez le thème personnalisé hors production.
Task 13: Use WP-CLI to mass-disable plugins (cleaner when available)
cr0x@server:~$ cd /var/www/wordpress
cr0x@server:~$ sudo -u www-data wp plugin deactivate --all
Plugin 'akismet' deactivated.
Plugin 'advanced-custom-fields' deactivated.
Success: Deactivated 12 of 12 plugins.
Ce que cela signifie : Les plugins sont désactivés au niveau WordPress (état en base), pas seulement masqués via le système de fichiers.
Décision : Si la désactivation corrige le WSOD, réactivez les plugins un par un jusqu’à ce que ça plante. Vous aurez alors l’offenseur.
Task 14: Check PHP memory limit and current PHP version
cr0x@server:~$ php -v
PHP 8.2.14 (cli) (built: Jan 15 2026 10:20:41) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.2.14, Copyright (c) Zend Technologies
with Zend OPcache v8.2.14, Copyright (c), by Zend Technologies
cr0x@server:~$ php -i | egrep -i "memory_limit|opcache.enable|max_execution_time" | head
memory_limit => 128M => 128M
max_execution_time => 30 => 30
opcache.enable => On => On
Ce que cela signifie : 128M est souvent juste pour les stacks WordPress modernes avec des page builders, des plugins lourds, ou de grandes options autoloadées.
Décision : Si les logs montrent une exhaustion de mémoire, augmentez memory_limit dans le pool PHP-FPM ou php.ini (pas seulement dans wp-config) et retestez.
Task 15: Spot a memory exhaustion fatal in logs
cr0x@server:~$ sudo grep -R "Allowed memory size" -n /var/log/nginx/error.log | tail -n 3
/var/log/nginx/error.log:9921:FastCGI sent in stderr: "PHP message: PHP Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 20480 bytes) in /var/www/wordpress/wp-includes/class-wpdb.php on line 2345"
Ce que cela signifie : Ce n’est pas un bug de thème ; c’est la mémoire. WordPress est mort dans le code de base de données parce que PHP a manqué de RAM.
Décision : Augmentez la limite de mémoire PHP et investiguez ce qui consomme la mémoire (boucles de plugin, grandes options autoloadées, requêtes énormes).
Task 16: Check database connectivity quickly (don’t assume, verify)
cr0x@server:~$ mysqladmin -u wpuser -p ping
Enter password:
mysqld is alive
Ce que cela signifie : La BD est joignable avec ces identifiants (au moins depuis cet hôte). Le WSOD n’est probablement pas « BD en panne ».
Décision : Poursuivez vers le code PHP/WordPress, sauf si les logs montrent des erreurs ou timeouts BD.
Task 17: Verify PHP-FPM is up and listening where Nginx expects
cr0x@server:~$ systemctl status php8.2-fpm --no-pager
● php8.2-fpm.service - The PHP 8.2 FastCGI Process Manager
Loaded: loaded (/lib/systemd/system/php8.2-fpm.service; enabled)
Active: active (running) since Tue 2026-02-04 09:01:22 UTC; 1h 13min ago
cr0x@server:~$ sudo ss -lxn | grep php8.2-fpm.sock
u_str LISTEN 0 4096 /run/php/php8.2-fpm.sock 12345678 * 0
Ce que cela signifie : Le service est en cours d’exécution, le socket écoute. Si vous obtenez toujours des pages vides, c’est probablement au niveau applicatif ou des permissions sur le socket.
Décision : Si le socket manque, redémarrez PHP-FPM ; si les permissions sont incorrectes, corrigez ownership/mode. Sinon, continuez l’investigation dans les logs.
Task 18: Check recent changes (packages, deploys) without lore
cr0x@server:~$ grep -E "upgrade|install" /var/log/dpkg.log | tail -n 8
2026-02-04 08:55:10 upgrade php8.2-fpm:amd64 8.2.13-1 8.2.14-1
2026-02-04 08:55:12 upgrade php8.2-cli:amd64 8.2.13-1 8.2.14-1
2026-02-04 08:55:15 upgrade nginx:amd64 1.24.0-1 1.24.0-2
Ce que cela signifie : PHP et Nginx ont été modifiés récemment. Les incompatibilités plugin/thème avec des versions PHP sont une cause fréquente de WSOD lors des mises à jour.
Décision : Si cela correspond au démarrage de l’incident, envisagez de revenir à la version précédente de PHP ou de patcher le plugin/thème incompatible.
Trois mini-récits d’entreprise tirés de la production
Mini-récit 1 : La panne causée par une mauvaise hypothèse
Dans une entreprise de taille moyenne où l’attitude était « WordPress, c’est juste le marketing », l’équipe plateforme a migré le site derrière un CDN avec un cache agressif. Ils ont fait un test rapide : la page d’accueil se charge, quelques pages internes se chargent, terminé. Ils ont supposé qu’une réponse 200 signifiait toujours « sain ».
Deux jours plus tard, une mise à jour de plugin a introduit une erreur fatale PHP sur un template spécifique utilisé par des pages de campagne. L’origine a commencé à renvoyer un 500 avec un corps vide pour ces pages. Le CDN, configuré pour mettre en cache les réponses « successful » uniquement d’après le code de statut, avait un bug dans une règle : il a mis en cache la réponse même lorsque le corps était vide à cause d’une condition mal spécifiée. Les visiteurs ont reçu un joli 200 et une page blanche. La surveillance n’a pas alerté car elle vérifiait le code de statut, pas la longueur du contenu ni un mot-clé.
L’ingénieur de garde a passé une heure à redémarrer des services parce que « c’est WordPress, ça reviendra ». Ça n’est pas revenu. L’erreur était déterministe. Une fois qu’ils ont contourné le CDN et vérifié l’origine directement, ils ont vu le 500 et le fatal PHP en moins d’une minute.
Ils ont corrigé le problème en changeant les health checks pour valider le contenu (un simple marqueur HTML), en ajustant les règles de cache pour éviter de mettre en cache les corps vides, et en faisant du « test de contournement d’origine » l’étape zéro du runbook d’incident.
Mini-récit 2 : L’optimisation qui s’est retournée contre eux
Une grande organisation a décidé de réduire la latence PHP en augmentant fortement les paramètres OPCache et en activant un préchargement agressif. Le changement a été déployé pendant une fenêtre de maintenance de routine. Tout avait l’air parfait : TTFB plus rapide, CPU en baisse. Tout le monde a célébré.
Puis les écrans blancs ont commencé — de façon intermittente. Pas à chaque requête, juste assez pour gâcher la journée. Le problème sous-jacent n’était pas WordPress du tout ; c’était la mécanique de déploiement. Leur processus de déploiement remplaçait des fichiers PHP in-place, et parfois mettait à jour des répertoires de plugins pendant que des workers PHP-FPM traitaient des requêtes. Avec le préchargement et des réglages d’opcache qui réduisaient les vérifications de stat, certains workers exécutaient un mélange d’anciens et de nouveaux chemins de code. Quand une classe a bougé, l’autoload a échoué, produisant des fatals qui se manifestaient par des pages blanches.
La correction était ennuyeuse : arrêter les remplacements de fichiers in-place. Déployer dans un nouveau répertoire de release, puis basculer le symlink de façon atomique. De plus, ajuster la validation d’OPCache pour leur modèle de déploiement plutôt que de copier des « meilleurs réglages » d’un article de blog de benchmark.
Les gains de performance sont réels, mais un « rapide » qui est parfois faux est juste une autre manière d’être en panne.
Mini-récit 3 : La pratique ennuyeuse qui a sauvé la mise
Une société de services financiers utilisait WordPress pour la documentation et l’intégration client. Rien de glamour, mais à fort impact. Ils avaient une règle stricte : chaque changement pouvant affecter le runtime disposait d’un chemin de rollback simple, et chaque hôte avait suffisamment de logs pour déboguer sans acrobaties SSH.
Quand le WSOD est survenu après une mise à jour de thème, la personne de garde n’a pas paniqué. Elle a consulté le tableau de bord : burn d’erreur, pics de fatals PHP-FPM, et une ligne de log claire pointant vers une fonction manquante. Ils sont revenus à la release précédente en secondes en basculant un symlink et en rechargeant PHP-FPM. Le site est revenu immédiatement.
Puis, en heures de travail, ils ont reproduit en staging avec la même version de PHP et le même ensemble de plugins, corrigé les vérifications de dépendances du thème (en protégeant les appels aux fonctions de plugin), et redéployé correctement. Le postmortem a été court parce que les faits étaient déjà capturés par les logs et la timeline des changements.
Ce n’était pas de l’héroïsme. C’était la compétence tranquille d’avoir des backups, des rollbacks et une télémétrie qui ne disparaît pas quand vous en avez besoin.
Erreurs fréquentes : symptôme → cause racine → correctif
Le dépannage WSOD échoue de manière prévisible. Voici les pièges habituels, avec des remèdes concrets.
1) Symptom: Home page is white, but some deep URLs work
Cause racine : Template du thème ou hook front-page déclenchant une erreur fatale ; parfois un shortcode de page builder sur la page d’accueil.
Correctif : Vérifiez les logs pour un fatal lié à la requête de la page d’accueil. Passez à un thème par défaut pour restaurer le service, puis corrigez le template.
2) Symptom: wp-admin is white, front-end is fine (or vice versa)
Cause racine : Plugin admin-only, mu-plugin, ou hook admin qui provoque un fatal. Ou un plugin de capacités qui casse l’initialisation admin.
Correctif : Désactivez tous les plugins et testez wp-admin spécifiquement. Vérifiez wp-content/mu-plugins pour les must-use plugins ; ils ne se désactivent pas comme les autres.
3) Symptom: HTTP 200 with empty body, only through CDN
Cause racine : Réponse vide en cache, mauvaise configuration de règle edge, ou origine renvoyant une réponse chunked mal gérée.
Correctif : Contournez le CDN et comparez. Purgez le cache pour les chemins affectés. Mettez à jour les règles de cache pour éviter de mettre en cache les corps vides et validez les réponses d’origine.
4) Symptom: White screen after updating PHP version
Cause racine : Plugin/thème utilisant des fonctionnalités dépréciées/supprimées, problèmes de typage strict, ou dépendances incompatibles.
Correctif : Identifiez la ligne du fatal ; mettez à jour ou remplacez le plugin/thème ; si nécessaire, revenez temporairement à la version PHP précédente. Ne « augmentez pas la mémoire » sans preuve.
5) Symptom: WSOD appears under load, disappears when traffic drops
Cause racine : Épuisement des workers PHP-FPM, requêtes lentes BD, deadlocks, ou timeouts d’API externes provoquant des requêtes longues et une défaillance en cascade.
Correctif : Vérifiez les réglages du pool PHP-FPM et les slow logs ; vérifiez le slow query log BD ; ajoutez des timeouts ; mettez en cache les appels externes. Scalez seulement après avoir compris la saturation.
6) Symptom: WSOD started after enabling a cache/minify plugin
Cause racine : JS/CSS minifié cassé ne donne pas WSOD (ça casse la mise en page). Mais les plugins de cache peuvent générer du HTML mis en cache vide, ou l’object cache peut empoisonner les résultats.
Correctif : Videz les caches du plugin, désactivez le plugin de cache, et supprimez les répertoires de cache générés. Confirmez la taille des octets de la réponse et le HTML, pas « ça a l’air parfois correct ».
7) Symptom: Only logged-in users see WSOD
Cause racine : Hooks spécifiques aux utilisateurs, admin bar, conflit de cache personnalisé, ou échec de gestion de session (disque plein, permissions).
Correctif : Testez avec une session navigateur propre. Vérifiez le chemin de sauvegarde des sessions et les permissions ; vérifiez l’espace disque ; désactivez les plugins qui modifient le flux d’auth/session.
8) Symptom: WSOD after “small config change” in wp-config.php
Cause racine : Erreur de syntaxe (guillemet/point-virgule manquant), encodage/espaces avant <?php, ou définitions en double de constantes.
Correctif : Lancez un lint PHP sur wp-config.php, restaurez depuis une copie connue bonne, et utilisez des templates de gestion de configuration au lieu d’éditions manuelles.
Blague #2 : Rien ne crie « entreprise » comme une panne de production causée par un point-virgule manquant dans un fichier nommé wp-config.php.
Listes de contrôle / plan étape par étape
Checklist incident : restaurer le service d’abord, puis corriger correctement
- Collecter les preuves : code de statut + en-têtes + taille du corps depuis le client et depuis l’origine. Sauvegardez-les dans vos notes d’incident.
- Tail des logs tout en reproduisant une fois : serveur web + PHP-FPM. Obtenez la ligne fatale.
- Activer temporairement WP_DEBUG_LOG si les logs ne montrent pas assez de détails.
- Désactiver les plugins en masse (renommer le répertoire plugins ou WP-CLI). Retester.
- Basculer vers un thème par défaut (renommer le répertoire du thème custom). Retester.
- Corriger la contrainte : mémoire/disque/permissions/incompatibilité PHP/etc.
- Rollback si nécessaire : revenir au dernier déploiement ou restaurer la dernière sauvegarde connue bonne.
- Désactiver la journalisation de debug et nettoyer les changements temporaires.
- Documenter la cause racine et la garde-fou pour éviter la récurrence (monitoring, tests, changement de déploiement).
Checklist d’isolation de plugin (la méthode rapide et sûre)
- Désactiver tous les plugins.
- Vérifier que le site se charge (front-end et wp-admin).
- Réactiver les plugins un par un, tester après chaque activation.
- Quand ça casse, vous avez trouvé le déclencheur. Laissez-le désactivé.
- Vérifier s’il existe une mise à jour compatible ; sinon, remplacez-le.
Checklist d’isolation de thème
- Passer à un thème par défaut.
- Si le site se charge, le thème personnalisé est coupable jusqu’à preuve du contraire.
- Rechercher dans le code du thème des appels directs aux fonctions de plugin ; protégez-les avec
function_exists(). - Corriger en staging avec la même version PHP et le même ensemble de plugins.
Checklist prévention permanente (le travail SRE que les gens sautent)
- Les health checks valident le contenu, pas seulement le HTTP 200.
- Les backups sont testés (drills de restauration), pas seulement « activés ».
- Les déploiements sont atomiques (releases via symlink), pas des remplacements de fichiers in-place.
- La rotation des logs existe et les alertes disque se déclenchent avant 95 % d’utilisation.
- La staging correspond à la production pour la version PHP et les extensions critiques.
- Verrouillez les mises à jour de plugins ou au moins regroupez-les avec des notes de rollback.
Faits et histoire intéressants (parce que ça ne date pas d’hier)
- WordPress a commencé en 2003 comme un fork de b2/cafelog ; l’écosystème de plugins a grandi rapidement, tout comme le rayon d’impact du code PHP tiers.
- Le terme « Écran blanc de la mort » prédates WordPress et a été popularisé dans d’autres écosystèmes (notamment les premiers Windows et plantages de consoles), mais le développement web l’a adopté pour les pages blanches sans erreur.
- Tôt, WordPress était souvent exécuté avec display_errors activé en hébergement mutualisé ; les stacks modernes cachent généralement les erreurs aux navigateurs, ce qui est plus sûr mais rend le WSOD silencieux.
- La sortie de PHP 7 (2015) a été un grand changement de performance ; elle a aussi exposé des problèmes de compatibilité dans de vieux plugins/thèmes, déclenchant souvent des WSOD lors des upgrades.
- PHP 8 a introduit plus de strictness et modifié les comportements d’erreur ; du code qui « fonctionnait par accident » peut commencer à provoquer des fatals, surtout dans les thèmes anciens.
- L’ordre de chargement des plugins WordPress compte : les mu-plugins se chargent avant les plugins normaux, et les thèmes peuvent exécuter du code tôt via functions.php — pratique pour la flexibilité, risqué pour les outages.
- Le caching peut rendre les échecs persistants : une fois qu’une réponse vide est mise en cache à l’edge, vous pouvez « réparer » l’origine et continuer à servir des pages blanches jusqu’à purge/expiration.
- Les incidents disque plein sont disproportionnellement fréquents dans les environnements WordPress à cause des uploads médias, des backups stockés localement, et des logs verbeux quand ça tourne mal.
- WSOD n’est pas toujours WordPress : des sockets PHP-FPM mal configurés, des fastcgi params incorrects, ou des refus SELinux/AppArmor peuvent tous se manifester par une page blanche.
FAQ
1) Pourquoi ma page WordPress est complètement blanche sans erreur ?
Parce que les erreurs ne s’affichent pas par défaut en production. PHP a probablement rencontré une erreur fatale ou une exhaustion de mémoire, et la sortie n’a jamais été rendue. Consultez les logs web/PHP ou activez brièvement WP_DEBUG_LOG.
2) Le WSOD est-il toujours causé par un plugin ?
Non. Les plugins sont fréquents, mais les thèmes, les mu-plugins, les mises à jour de version PHP, les conditions disque plein et les couches de cache peuvent tous produire le même symptôme : rien.
3) Quelle est la façon la plus rapide de récupérer lorsque wp-admin est aussi blanc ?
Désactivez les plugins en renommant wp-content/plugins, puis changez le thème en renommant le répertoire du thème actif. Cela contourne complètement wp-admin.
4) Dois-je activer WP_DEBUG en production ?
Temporairement, avec WP_DEBUG_DISPLAY réglé sur false et WP_DEBUG_LOG true. Capturez l’erreur, puis désactivez. Laisser le debug activé longtemps peut divulguer des chemins sensibles et remplir les disques.
5) J’obtiens HTTP 200 mais la page est vide. Comment est-ce possible ?
Les codes de statut peuvent mentir par omission. Un reverse proxy peut renvoyer 200 avec un corps vide depuis le cache, ou PHP peut avoir envoyé les en-têtes avant de planter. Vérifiez la taille du corps de la réponse et les en-têtes de cache, puis comparez origine vs edge.
6) J’ai augmenté la mémoire dans wp-config.php mais le WSOD persiste. Pourquoi ?
Parce que la limite effective est souvent fixée dans la configuration du pool PHP-FPM ou php.ini. De plus, tous les WSOD ne sont pas liés à la mémoire. Confirmez avec des logs montrant « Allowed memory size exhausted » avant de changer les limites.
7) Un problème de base de données peut-il causer un WSOD au lieu d’« Error establishing a database connection » ?
Oui. Des requêtes lentes, des tables verrouillées ou des timeouts peuvent se propager en saturation PHP-FPM, conduisant à des réponses vides. Mais vous devriez quand même voir des timeouts dans les logs. Vérifiez la santé BD et consultez les slow logs si c’est lié à la charge.
8) Que faire si désactiver plugins et changer de thème ne résout pas ?
Alors c’est probablement en dessous de WordPress : PHP-FPM arrêté, socket manquant, permissions/SELinux, extensions PHP manquantes, disque plein, ou une régression de configuration du serveur web. Revenez au statut des services et aux logs.
9) Comment savoir si c’est Cloudflare (ou un autre CDN) plutôt que mon serveur ?
Comparez les requêtes en utilisant des en-têtes de contournement de cache et interrogez l’origine directement si possible. Si l’origine renvoie du HTML normal et que le CDN renvoie du vide, le problème est à l’edge — purgez ou corrigez les règles de cache.
10) Après la récupération, quelle est l’étape de prévention avec le meilleur ROI ?
Des health checks qui valident le contenu plus un processus de déploiement réversible et atomic. Ces deux éléments transforment une « page blanche mystère » en un incident rapide et borné.
Prochaines étapes à faire réellement
Le WSOD ressemble à WordPress qui fait le spectacle. En réalité, c’est votre stack qui vous dit : « Je me suis planté, et vous n’avez pas relié la sortie d’erreur à un endroit pratique. » La correction n’est pas un flag magique ; c’est une séquence reproductible.
- Maintenant : exécutez le playbook de diagnostic rapide. Capturez statut/octets, contournez le cache, tail des logs, reproduisez une fois.
- Récupérez le service : désactivez les plugins en masse, basculez vers un thème par défaut, ou revenez au dernier déploiement.
- Corrigez la cause racine : patch/replace le plugin/thème fautif, corrigez l’incompatibilité de version PHP, augmentez la mémoire uniquement sur preuve, et résolvez les contraintes disque/permissions.
- Prévenez la récurrence : ajoutez des health checks basés sur le contenu, assurez la rotation des logs + alertes disque, et adoptez des déploiements atomiques avec rollback simple.
Vous n’avez pas besoin d’héroïsme. Vous avez besoin de preuves, d’isolation, et de la discipline d’arrêter d’« optimiser » ce que vous n’avez pas mesuré.