Écran blanc de la mort WordPress (WSOD) : 12 vérifications qui fonctionnent vraiment

Cet article vous a aidé ?

L’écran blanc de la mort est la manière dont WordPress dit « quelque chose a explosé » tout en refusant de dire où les éclats sont tombés. Les utilisateurs voient une page blanche. Votre supervision affiche « 200 OK ». Votre ingénieur d’astreinte envisage sa propre mortalité.

Ceci est le guide que j’aimerais voir appliqué par plus d’équipes : triage rapide d’abord, puis vérifications disciplinées qui transforment le mystère en une cause racine unique que vous pouvez réparer et prévenir.

Playbook de diagnostic rapide (premières 10 minutes)

La rapidité compte, mais deviner prend plus de temps que de lire le bon journal une fois. L’objectif est d’identifier l’endroit du goulot d’étranglement : l’échec survient-il avant l’exécution de PHP, dans PHP, ou après PHP (base de données/cache/stockage) ?

Minute 0–2 : confirmer ce que « blanc » signifie

  • Vérifier le statut HTTP et les en-têtes. Un 500 avec un corps vide n’est pas la même chose qu’un 200 qui renvoie seulement des espaces.
  • Comparer la page d’accueil et wp-admin. Si wp-admin se charge, il s’agit souvent du thème/du plugin front-end, et non d’un runtime global.
  • Contourner le CDN et les caches. Si l’origine est correcte et que le bord renvoie du vide, vous déboguez le mauvais système.

Minute 2–5 : lire les journaux comme un adulte

  • Journal d’erreurs du serveur web (Nginx/Apache) pour les échecs en amont et les timeouts.
  • Journal PHP-FPM / journal d’erreurs PHP pour les erreurs fatales, l’épuisement mémoire, les problèmes d’OPcache.
  • Fatal côté application via le journal de debug WordPress si vous pouvez l’activer en toute sécurité.

Minute 5–10 : isoler plugins/thèmes sans toucher au code

  • Désactiver tous les plugins (WP-CLI ou renommer le répertoire) et retester.
  • Basculer vers un thème par défaut connu fonctionnel.
  • Si c’est toujours blanc, arrêtez de blâmer « un plugin » et examinez les incompatibilités de version PHP, les extensions manquantes, la connectivité BD, le disque et la mémoire.

Un modèle mental utile : WSOD n’est rarement « WordPress est en panne ». C’est généralement « PHP a rencontré une erreur fatale et le buffering a produit rien » ou « le runtime ne peut pas lire/écrire les fichiers requis et échoue en chemin ».

Quelques faits (et petite histoire) à propos du WSOD

  • Le WSOD existe avant WordPress. Le terme s’est populaire dans l’écosystème PHP quand les erreurs fatales étaient supprimées en production, laissant une sortie vide.
  • WordPress échouait silencieusement par défaut. Les configurations anciennes avaient souvent display_errors désactivé sans journal centralisé, faisant du WSOD un comportement courant.
  • « Le mode de récupération » est relativement récent. WordPress a introduit une protection/recouvrement contre les erreurs fatales (ère 5.2) qui peut envoyer des e-mails aux admins et permettre de désactiver un plugin/thème cassé. Utile, mais pas omniscient.
  • Le WSOD peut être un 200 OK. Beaucoup d’échecs surviennent après l’envoi des en-têtes ou sont gérés de manière à retourner un corps vide avec un statut de succès — donc les tests d’état sont trompeurs.
  • OPcache a rendu le WSOD à la fois meilleur et pire. Il améliore les performances, mais du bytecode périmé après un déploiement peut continuer d’exécuter du code ancien même si les fichiers ont changé.
  • PHP moderne est plus strict. Les montées de version PHP peuvent transformer des « avertissements ignorés depuis des années » en fatales à cause de fonctions supprimées ou d’un typage plus strict.
  • L’épuisement de mémoire reste une cause majeure. Particulièrement avec les page builders, de grosses installations WooCommerce, et des plugins de sécurité « utiles » qui font des opérations coûteuses à chaque requête.
  • Les problèmes de stockage se déguisent souvent en WSOD. Un disque plein, un système de fichiers en lecture seule, ou un NFS lent peuvent faire échouer les écritures de sessions/uploads/cache, entraînant des pages blanches.
  • Les CDN peuvent mettre en cache du vide. Si l’origine renvoie brièvement une réponse vide 200, le bord peut servir ce vide à tout le monde jusqu’à expiration.

Une citation que chaque incident WSOD prouve en silence : Tout échoue, tout le temps. — Werner Vogels

Les 12 vérifications qui fonctionnent vraiment (avec commandes, sorties, décisions)

Chaque vérification ci‑dessous est une tâche réelle : une commande à exécuter, ce que signifie la sortie, et la décision à prendre. Faites-les dans l’ordre sauf si vous avez déjà une preuve évidente.

Blague #1 : WSOD, c’est comme une réunion sans ordre du jour : tout le monde est présent, rien n’avance, et d’une manière ou d’une autre vous perdez de l’argent.

Vérification 1) Confirmer le mode d’échec avec curl (statut, en-têtes, taille du corps)

cr0x@server:~$ curl -sS -D- -o /tmp/body.html -w "\nstatus=%{http_code} size=%{size_download} time=%{time_total}\n" https://example.com/ | head -n 20
HTTP/2 200
date: Thu, 26 Dec 2025 14:21:09 GMT
content-type: text/html; charset=UTF-8
cache-control: max-age=0, must-revalidate
server: nginx

status=200 size=0 time=0.312

Ce que ça signifie : Un 200 avec size=0 est un comportement classique de WSOD : la requête a réussi au niveau HTTP, mais n’a généré aucun corps (ou a été tronquée).

Décision : Traitez cela comme une défaillance d’application/runtime, pas comme « le serveur web est tombé ». Passez aux journaux et à PHP-FPM.

Vérification 2) Contourner le CDN / cache edge pour prouver le comportement de l’origine

cr0x@server:~$ curl -sS -H "Cache-Control: no-cache" -H "Pragma: no-cache" -D- -o /dev/null https://example.com/
HTTP/2 200
date: Thu, 26 Dec 2025 14:21:31 GMT
content-type: text/html; charset=UTF-8
cf-cache-status: HIT
server: cloudflare

Ce que ça signifie : Le bord sert du contenu mis en cache (peut-être du vide mis en cache). Votre requête « no-cache » n’a pas forcé l’origine.

Décision : Testez directement l’origine en ciblant l’IP de l’origine/le header Host ou l’adresse du LB interne. Si l’origine est bonne, purgez le cache edge ; si l’origine est cassée, arrêtez d’examiner le CDN.

Vérification 3) Regarder d’abord les erreurs du serveur web (exemple Nginx)

cr0x@server:~$ sudo tail -n 80 /var/log/nginx/error.log
2025/12/26 14:20:58 [error] 23144#23144: *9181 FastCGI sent in stderr: "PHP message: PHP Fatal error:  Uncaught Error: Call to undefined function mysql_connect() in /var/www/html/wp-content/plugins/legacy-db/legacy.php:41" while reading response header from upstream, client: 203.0.113.10, server: example.com, request: "GET / HTTP/2.0", upstream: "fastcgi://unix:/run/php/php8.2-fpm.sock:", host: "example.com"

Ce que ça signifie : C’est de l’or : une erreur fatale dans un plugin appelant une fonction supprimée. PHP n’a jamais produit de réponse valide.

Décision : Désactivez immédiatement ce plugin. Puis planifiez une correction de code ou un remplacement. Vérifiez aussi pourquoi cela a atteint la production (plus loin sur ce sujet).

Vérification 4) Vérifier l’état du service PHP-FPM et les crashs récents

cr0x@server:~$ sudo 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 Thu 2025-12-26 14:00:01 UTC; 21min ago
   Main PID: 1109 (php-fpm8.2)
      Tasks: 19 (limit: 18962)
     Memory: 214.5M
        CPU: 1min 42.110s
     CGroup: /system.slice/php8.2-fpm.service
             ├─1109 "php-fpm: master process (/etc/php/8.2/fpm/php-fpm.conf)"
             └─1132 "php-fpm: pool www"

Ce que ça signifie : PHP-FPM est actif. Cela ne veut pas dire qu’il est sain ; cela signifie seulement qu’il est vivant. Vous devez quand même inspecter les journaux pour des crashes de workers, des limites de children, des requêtes lentes.

Décision : Si PHP-FPM est arrêté ou instable, corrigez cela en priorité (config, mémoire, segfaults, problèmes de paquets). S’il est actif, poursuivez l’examen des journaux.

Vérification 5) Lire le journal PHP-FPM pour des motifs fatals (mémoire, timeouts, segfaults)

cr0x@server:~$ sudo tail -n 120 /var/log/php8.2-fpm.log
[26-Dec-2025 14:20:58] WARNING: [pool www] child 1733 said into stderr: "PHP Fatal error:  Allowed memory size of 268435456 bytes exhausted (tried to allocate 4096 bytes) in /var/www/html/wp-includes/class-wpdb.php on line 2345"
[26-Dec-2025 14:21:03] WARNING: [pool www] child 1735 exited on signal 11 (SIGSEGV) after 2.412340 seconds from start
[26-Dec-2025 14:21:03] NOTICE: [pool www] child 1741 started

Ce que ça signifie : Deux problèmes distincts peuvent coexister : épuisement mémoire (généralement déterministe par requête) et segfaults (souvent bugs d’extension, OPcache, ou mémoire corrompue). Chacun peut provoquer un WSOD.

Décision : Pour l’épuisement mémoire : identifiez la requête/plugin/thème responsable ; augmentez les limites seulement après en avoir identifié la cause. Pour les segfaults : vérifiez les extensions (Redis, Imagick), OPcache, version PHP ; envisagez un rollback ou la désactivation de l’extension.

Vérification 6) Activer le logging de debug WordPress en toute sécurité (pas display_errors)

En production, vous voulez des journaux, pas des erreurs publiques. Éditez wp-config.php pour écrire dans un fichier. Puis reproduisez la requête une fois.

cr0x@server:~$ sudo -u www-data sed -n '1,120p' /var/www/html/wp-config.php | tail -n 20
define('WP_DEBUG', false);
define('WP_DEBUG_LOG', false);
define('WP_DEBUG_DISPLAY', false);

Changer (temporairement) en :

cr0x@server:~$ sudo -u www-data perl -0777 -pe 's/define\(\x27WP_DEBUG\x27,\s*false\);/define(\x27WP_DEBUG\x27, true);/; s/define\(\x27WP_DEBUG_LOG\x27,\s*false\);/define(\x27WP_DEBUG_LOG\x27, true);/; s/define\(\x27WP_DEBUG_DISPLAY\x27,\s*false\);/define(\x27WP_DEBUG_DISPLAY\x27, false);/' -i /var/www/html/wp-config.php

Puis appelez le site et lisez :

cr0x@server:~$ sudo tail -n 80 /var/www/html/wp-content/debug.log
[26-Dec-2025 14:22:15 UTC] PHP Fatal error:  Uncaught TypeError: strpos(): Argument #1 ($haystack) must be of type string, null given in /var/www/html/wp-content/themes/custom/functions.php:912
Stack trace:
#0 /var/www/html/wp-content/themes/custom/functions.php(912): strpos()
#1 /var/www/html/wp-includes/class-wp-hook.php(324): theme_filter()

Ce que ça signifie : Le code du thème plante. Cela peut rendre le front-end vide tandis que wp-admin fonctionne encore.

Décision : Changez de thème maintenant ; corrigez le thème après la restauration du service. Rétablissez les réglages de debug après avoir capturé l’erreur (ou conservez le logging, mais faites une rotation).

Vérification 7) Désactiver tous les plugins avec WP-CLI (rapide, réversible)

cr0x@server:~$ cd /var/www/html
cr0x@server:~$ sudo -u www-data wp plugin list --status=active
+---------------------+--------+-----------+---------+
| name                | status | update    | version |
+---------------------+--------+-----------+---------+
| redis-cache         | active | none      | 2.5.2   |
| legacy-db           | active | available | 1.3.1   |
| woo-commerce        | active | none      | 8.5.0   |
+---------------------+--------+-----------+---------+
cr0x@server:~$ sudo -u www-data wp plugin deactivate --all
Plugin 'redis-cache' deactivated.
Plugin 'legacy-db' deactivated.
Plugin 'woo-commerce' deactivated.
Success: Deactivated 3 of 3 plugins.

Ce que ça signifie : Vous avez retiré la plus grande variable : le code des plugins. Si le WSOD disparaît, réactivez-les un par un (recherche binaire s’il y en a beaucoup).

Décision : Si la désactivation des plugins résout le problème : réactivez jusqu’à ce que ça casse ; puis corrigez/remplacez le coupable. Si ce n’est pas réparé : examinez le thème/runtime/BD/stockage.

Vérification 8) Basculer vers un thème par défaut sans l’interface admin

Si le front-end est en panne mais que vous ne pouvez pas entrer dans wp-admin, changer le thème via la CLI est propre.

cr0x@server:~$ sudo -u www-data wp theme list
+----------------+----------+-----------+---------+
| name           | status   | update    | version |
+----------------+----------+-----------+---------+
| twentytwentyfour | inactive | none      | 1.2     |
| custom         | active   | none      | 3.8     |
+----------------+----------+-----------+---------+
cr0x@server:~$ sudo -u www-data wp theme activate twentytwentyfour
Success: Switched to 'Twenty Twenty-Four' theme.

Ce que ça signifie : Vous avez remplacé le chemin d’exécution qui rend la plupart des pages. Les WSOD se trouvent fréquemment dans functions.php ou dans un fichier « utilitaire » du thème.

Décision : Si cela restaure le site, laissez le thème par défaut actif pendant que vous corrigez le thème personnalisé. L’équipe marque survivra.

Vérification 9) Vérifier la version PHP, les modules chargés et les extensions manquantes

cr0x@server:~$ php -v
PHP 8.2.12 (cli) (built: Nov  8 2025 10:12:34) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.2.12, Copyright (c) Zend Technologies
    with Zend OPcache v8.2.12, Copyright (c), by Zend Technologies
cr0x@server:~$ php -m | egrep -i 'mysqli|pdo_mysql|imagick|redis|opcache'
mysqli
PDO
pdo_mysql
redis
Zend OPcache

Ce que ça signifie : Les bases sont présentes. Si vous manquez mysqli ou pdo_mysql, WordPress peut échouer sévèrement. Si imagick est absent, certains plugins/thèmes peuvent provoquer une erreur fatale s’ils supposent son existence.

Décision : Si une extension requise manque, installez-la ou modifiez le plugin/thème qui la suppose. Aussi : assurez-vous que les versions PHP-FPM et CLI correspondent ; les discordances créent du « marche en CLI, casse sur le web ».

Vérification 10) Confirmer les limites mémoire côté PHP et WordPress

cr0x@server:~$ php -r 'echo "memory_limit=".ini_get("memory_limit").PHP_EOL;'
memory_limit=256M
cr0x@server:~$ grep -R "WP_MEMORY_LIMIT" -n /var/www/html/wp-config.php
42:define('WP_MEMORY_LIMIT', '128M');
43:define('WP_MAX_MEMORY_LIMIT', '256M');

Ce que ça signifie : WordPress peut limiter la mémoire à une valeur inférieure à la configuration globale PHP. Les requêtes d’administration utilisent WP_MAX_MEMORY_LIMIT ; le front-end utilise WP_MEMORY_LIMIT. Un WSOD qui n’affecte que wp-admin peut être l’inverse.

Décision : Si vous rencontrez des fatales mémoire, augmentez temporairement WP_MEMORY_LIMIT pour qu’il corresponde à PHP, mais ne vous arrêtez pas là. Trouvez la requête lourde, la boucle incontrôlée, ou le plugin qui fait un travail non borné. Augmenter la mémoire n’est qu’un pansement.

Vérification 11) Valider la connectivité à la base de données et chercher « too many connections »

WordPress peut renvoyer du vide quand les appels BD échouent en plein rendu, surtout si les erreurs sont supprimées et que le thème ne gère pas les valeurs nulles.

cr0x@server:~$ mysql -h 127.0.0.1 -u wpuser -p -e "SELECT 1;"
Enter password:
1
1
cr0x@server:~$ mysql -h 127.0.0.1 -u root -p -e "SHOW STATUS LIKE 'Threads_connected'; SHOW VARIABLES LIKE 'max_connections';"
Enter password:
Threads_connected	148
max_connections	150

Ce que ça signifie : Vous frôlez le plafond de connexions. Lors d’un pic, les workers PHP font la queue et la BD rejette des connexions. Selon la gestion des erreurs, vous pouvez obtenir un WSOD.

Décision : Court terme : réduire la concurrence (PHP-FPM pm.max_children), ou augmenter max_connections si l’hôte peut le supporter. Long terme : optimiser les requêtes, ajouter un cache correctement, et arrêter d’exécuter des « analytics lents » dans le chemin de requête.

Vérification 12) Sanité du stockage : disque plein, inodes, permissions, montages en lecture seule

Les problèmes de stockage sont les assassins silencieux des applications PHP : les sessions ne s’écrivent plus, le cache ne se met pas à jour, les uploads échouent, et les chemins de code se comportent étrangement quand les opérations de fichier retournent false.

cr0x@server:~$ df -h /var/www /tmp
Filesystem      Size  Used Avail Use% Mounted on
/dev/vda1        40G   39G  160M 100% /
tmpfs           1.0G  1.0G     0 100% /tmp
cr0x@server:~$ df -i /
Filesystem     Inodes IUsed  IFree IUse% Mounted on
/dev/vda1     262144 262144     0  100% /
cr0x@server:~$ mount | grep ' on / '
/dev/vda1 on / type ext4 (ro,relatime,errors=remount-ro)

Ce que ça signifie : Triple problème : disque plein, inodes épuisés, et système de fichiers remonté en lecture seule. WordPress ne gérera pas cela proprement ; il échouera simplement à écrire des fichiers critiques et cela peut apparaître comme un WSOD.

Décision : Restaurez d’abord la capacité d’écriture et libérez de l’espace. Supprimez des logs, videz les répertoires temporaires, faites une rotation correcte, et investigatez pourquoi le système de fichiers est passé en lecture seule (erreurs disque sous-jacentes, noyau). Ne perdez pas de temps à réinstaller des plugins tant que votre disque est en feu.

Vérification bonus) OPcache : quand les déploiements « réussissent » mais le code ne change pas

Celui‑ci est si courant en production qu’il mérite une place même s’il rend la liste « 12 plus un bonus ». Si vous ne pouvez avoir que douze vérifications, remplacez celle que vous jugez la moins utile.

cr0x@server:~$ php -r 'echo "opcache.enable=".ini_get("opcache.enable").PHP_EOL; echo "opcache.validate_timestamps=".ini_get("opcache.validate_timestamps").PHP_EOL; echo "opcache.revalidate_freq=".ini_get("opcache.revalidate_freq").PHP_EOL;'
opcache.enable=1
opcache.validate_timestamps=0
opcache.revalidate_freq=2

Ce que ça signifie : Avec la validation des timestamps désactivée, PHP peut ne jamais remarquer les changements de code tant que FPM n’est pas redémarré. Cela peut maintenir une version cassée en exécution même après que vous ayez « corrigé » les fichiers.

Décision : Dans des modèles de déploiement immuables, cela peut être acceptable si vous redémarrez PHP-FPM lors du déploiement. Sinon, activez la validation ou ajoutez une étape explicite de reload. La cohérence opérationnelle prime sur l’ingéniosité.

Blague #2 : « Ça marche sur mon laptop » est adorable. La production n’est pas adorable.

Trois mini-histoires d’entreprise depuis le terrain

Mini-histoire 1 : L’incident causé par une mauvaise hypothèse (la montée de version PHP « devrait aller »)

Une entreprise de taille moyenne gérait un site WordPress riche en contenu derrière un reverse proxy Nginx. Ils avaient aussi une ferme de microsites marketing séparée. Un mardi calme, ils ont mis à jour l’image de base pour tous les services PHP, passant de PHP 7.4 à PHP 8.2. C’était planifié, approuvé, et « testé ».

L’hypothèse erronée était simple : si la page d’accueil de staging se charge, la production se chargera. Leur environnement de staging avait un ensemble de plugins différent — à cause des licences. Le plugin legacy qui gérait une ancienne intégration de base de données n’était pas installé en staging, et personne ne l’a remarqué parce qu’il « ne devait plus importer ». Sauf que si, ça importait.

La production a commencé à renvoyer un 200 vide pour la page d’accueil. La supervision est restée verte parce que leur health check frappait /robots.txt, qui était statique. Les tickets support ont afflué. L’ingénieur d’astreinte a vu le 200 et a d’abord blâmé le CDN. Dix minutes ont disparu en purge de caches et redéploiements.

La réparation a été rapide une fois qu’ils ont regardé les erreurs Nginx : une fatale provenant d’une fonction PHP supprimée. Ils ont désactivé le plugin via WP-CLI, restauré le service, puis l’ont remplacé par une intégration supportée.

La prévention fut moins glamour : leur politique « parité staging » exige maintenant la même liste de plugins (même si configurés différemment), et les montées de version exigent une transaction synthétique frappant des endpoints WordPress dynamiques, pas des fichiers statiques.

Mini-histoire 2 : L’optimisation qui a mal tourné (cache d’objets sans garde-fous)

Une équipe enterprise gérait un site WordPress qui subissait des pics lors de communiqués de presse. Quelqu’un a proposé le cache d’objets Redis pour réduire la charge BD. Bonne idée. Ils l’ont déployé rapidement, ont célébré la baisse d’utilisation CPU BD, et sont passés au prochain incendie.

Des semaines plus tard, une mise à jour de plugin a introduit un bug subtil : il mettait en cache un gros graphe d’objets PHP sous une clé qui variait par user-agent et certains paramètres de requête. Les clés de cache ont explosé. La mémoire Redis s’est remplie, l’éviction est devenue agressive, et la latence a augmenté. Sous charge, les requêtes PHP ont commencé à timeout en attendant des appels Redis.

De l’extérieur, le site ressemblait à un WSOD : pages blanches ou à moitié rendues. En interne, Nginx montrait des timeouts upstream. PHP-FPM avait beaucoup de workers actifs bloqués. La base de données allait bien, ce qui a induit l’équipe en erreur parce qu’« on a réglé la BD ». Ils n’avaient pas résolu le chemin de requête ; ils avaient juste déplacé le goulot vers une nouvelle machine.

Le rollback a été de désactiver immédiatement le cache d’objets (renommer le drop-in), puis de le réintroduire avec des contraintes : TTLs raisonnables, caps mémoire, discipline des clés, et une règle que les bugs de cache sont des outages de production, pas des « problèmes de performance ».

La leçon : le cache est un outil tranchant. Si vous le brandissez dans une pièce bondée, quelqu’un saigne.

Mini-histoire 3 : La pratique ennuyeuse mais correcte qui a sauvé la journée (journaux, rotation et un canari)

Une équipe de services financiers utilisait WordPress pour une base de connaissances. Rien d’excitant, beaucoup de conformité. Leurs pratiques n’étaient pas excitantes : journaux centralisés, rotation stricte des logs, checklist de déploiement, et un hôte canari qui recevait d’abord le trafic des utilisateurs internes.

Un jour, une mise à jour de thème a introduit une erreur fatale sur un template de page rarement utilisé. L’hôte canari a immédiatement commencé à journaliser la fatale. Comme les logs étaient centralisés, l’astreinte n’a pas eu besoin d’SSH héroïque ; elle a vu la stack trace exacte dans un tableau de bord et a rollbacké le paquet du thème.

Les utilisateurs externes n’ont jamais vu de WSOD. Le changement a été reverté avant la phase de déploiement public. Pas de drame, pas de war room, pas de « peut-être c’est le DNS ».

C’est la partie que les gens détestent : la bonne solution n’était pas une commande astucieuse. C’était un processus terne et de l’observabilité. Le terne est une fonctionnalité quand vous êtes responsable de la disponibilité.

Erreurs fréquentes : symptôme → cause racine → correction

1) Page blanche uniquement sur la page d’accueil

  • Symptôme : / est blanc ; /wp-admin fonctionne.
  • Cause racine : Plantage d’un template de thème, hook plugin front-end, ou une fatale dans un shortcode utilisé sur la page d’accueil.
  • Correction : Changez de thème via WP-CLI ; désactivez les plugins front-end ; vérifiez le debug log pour la stack trace ; réintroduisez les changements un par un.

2) Page blanche après mise à jour d’un plugin

  • Symptôme : Le site devient blanc immédiatement après la mise à jour d’un plugin.
  • Cause racine : Fatale due à une incompatibilité de version PHP, extension manquante, ou autoloader/mauvaise redéclaration de classe.
  • Correction : Désactivez le plugin via WP-CLI ; vérifiez la version PHP ; rollback du plugin ; testez la mise à jour en staging paritaire.

3) Page blanche uniquement pour les utilisateurs connectés

  • Symptôme : Les visiteurs anonymes voient le site ; les admins voient un WSOD.
  • Cause racine : Plugins réservés à l’administration, widgets de tableau de bord, ou différences de limite mémoire (WP_MAX_MEMORY_LIMIT).
  • Correction : Augmentez temporairement la mémoire admin ; désactivez les plugins admin ; vérifiez les logs PHP-FPM pour épuisement mémoire ; profilez les pages admin lentes.

4) Page blanche intermittente sous charge

  • Symptôme : Fonctionne parfois ; blanche pendant les pics.
  • Cause racine : Épuisement des workers PHP-FPM, timeouts upstream, limites de connexions BD, latence Redis, ou stockage lent.
  • Correction : Vérifiez les timeouts Nginx upstream, pm.max_children de PHP-FPM, Threads_connected de la BD, latence Redis. Réduisez la concurrence ou optimisez le chemin lent.

5) WSOD apparu « après avoir nettoyé les caches »

  • Symptôme : Vider le cache semble déclencher des pages blanches.
  • Cause racine : Le plugin de cache écrit sur disque/tmp, mais le disque est plein ou le système de fichiers est en lecture seule ; ou permissions incorrectes sur wp-content.
  • Correction : Vérifiez disque/inodes, flags de montage, propriété sur wp-content ; corrigez le stockage d’abord, puis reconstruisez les caches.

6) WSOD après activation d’un durcissement de sécurité

  • Symptôme : Le site devient blanc après activation d’une règle WAF, d’un plugin de hardening, ou d’un changement de permissions de fichiers.
  • Cause racine : Blocage d’admin-ajax/admin-post, blocage des endpoints REST, ou empêchant PHP de lire les fichiers de thème/plugin.
  • Correction : Examinez les logs WAF ; revenez à des permissions saines connues ; assurez-vous que l’utilisateur PHP peut lire le code et écrire uploads/cache là où nécessaire.

Listes de contrôle / plan étape par étape (restaurer le service, puis prévenir)

Phase 1: Restaurer le service (priorité : impact utilisateur)

  1. Confirmer le mode WSOD avec curl (statut, taille, temps de réponse).
  2. Contourner caches/CDN et tester l’origine.
  3. Lire les journaux du serveur web et de PHP-FPM pour erreurs fatales et timeouts.
  4. Désactiver tous les plugins (WP-CLI). Retester.
  5. Basculer vers un thème par défaut. Retester.
  6. Vérifier disque/inodes et état de montage (plein/lecture seule tue WordPress rapidement).
  7. Vérifier la connectivité BD et la saturation des connexions.
  8. Rollback du dernier changement (plugin/thème/version PHP) si la cause n’est pas évidente sous 30 minutes.

Phase 2: Identifier la cause exacte (priorité : ne pas répéter)

  1. Capturer la première stack trace fatale (journal de debug WordPress ou journal d’erreurs PHP).
  2. Reproduire dans un environnement contrôlé avec le même ensemble plugins/thèmes et version PHP.
  3. Localiser la requête déclencheuse : page d’accueil, shortcode, cron, admin-ajax, route REST.
  4. Corriger le bug ou remplacer le composant ; ajouter un test de régression (même un curl synthétique bon marché qui vérifie du HTML non vide).
  5. Décider s’il faut ajuster mémoire/timeouts — seulement après avoir compris le chemin de code.

Phase 3: Prévention (priorité : que votre futur vous puisse dormir)

  • Staging paritaire : même liste de plugins, même version PHP, mêmes couches de cache.
  • Journaux centralisés : Nginx/Apache + PHP-FPM + journal debug WordPress (avec rotation).
  • Discipline de déploiement : redémarrer PHP-FPM quand la validation OPcache des timestamps est désactivée ; éviter les « déploiements partiels ».
  • Vrais health checks : frapper des endpoints dynamiques et valider la taille du corps, pas seulement le code de statut.
  • Surveillance du stockage : alertes sur % disque, % inode, et événements de remontage en lecture seule.

FAQ

1) Pourquoi j’obtiens une page blanche avec HTTP 200 ?

Parce que la requête se termine au niveau HTTP, mais PHP ne produit aucune sortie — souvent à cause d’une erreur fatale, du buffering, ou d’une coupure d’output. Les journaux disent la vérité.

2) Dois‑je activer display_errors en production ?

Non. Journalisez les erreurs à la place. L’affichage public des erreurs est une fuite d’informations et peut casser davantage les réponses. Activez WP_DEBUG_LOG et gardez WP_DEBUG_DISPLAY à false.

3) Quelle est la manière la plus rapide pour exclure les plugins ?

WP-CLI : wp plugin deactivate --all. Si vous n’avez pas WP-CLI, renommez wp-content/plugins en autre chose et retestez.

4) Un thème peut‑il vraiment causer un WSOD ?

Oui. Les thèmes exécutent du PHP. Une fatale dans functions.php ou une partie de template peut rendre le site aussi vide qu’un plugin défaillant.

5) Pourquoi le WSOD arrive‑t‑il seulement parfois ?

Le WSOD intermittent signifie généralement une contention de ressources : workers PHP-FPM épuisés, connexions BD au maximum, latence de cache, ou blocages de stockage. Cherchez des timeouts et des métriques de saturation, pas seulement des fatales.

6) Et si wp-admin est aussi blanc ?

Cela indique un problème global : un must-use plugin, un fichier core incompatible, un crash d’extension PHP, une défaillance BD, ou un problème de stockage/permissions. Commencez par les journaux, puis désactivez plugins/thèmes depuis le système de fichiers ou la base de données.

7) Comment changer le thème si WP-CLI n’est pas disponible ?

Modifiez les options de la base de données template et stylesheet vers un thème par défaut. Ou restaurez WP-CLI ; c’est plus sûr que du SQL manuel quand vous êtes stressé.

8) OPcache peut‑il causer un WSOD ?

Indirectement, oui : du bytecode périmé peut continuer d’exécuter du code cassé après que vous ayez « corrigé » les fichiers. Si vous déployez sans redémarrer PHP-FPM et que la validation des timestamps OPcache est désactivée, vous jouez aux dés.

9) Augmenter la limite mémoire est‑ce une solution valide ?

Comme mitigation temporaire, parfois. Comme correction finale, rarement. Si une requête nécessite soudainement le double de mémoire, quelque chose a changé : mise à jour de plugin, requête, boucle infinie, ou croissance de payload.

10) Comment empêcher le CDN de mettre en cache la page vide ?

Purger les chemins affectés et assurez‑vous que votre origine ne renvoie pas des 200 vides pendant les pannes. Configurez les règles edge pour respecter les statuts d’erreur, et envisagez un check synthétique qui valide du HTML non vide.

Prochaines étapes (pratiques, pas inspirantes)

Faites ceci la prochaine fois que le WSOD frappe :

  1. Exécutez curl et confirmez le statut, la taille, et si vous regardez le cache edge ou l’origine.
  2. Lisez les journaux Nginx/Apache et PHP-FPM avant de changer quoi que ce soit d’autre.
  3. Désactivez les plugins, changez de thème, et retestez — l’isolation rapide bat la réflexion lente.
  4. Vérifiez disque/inodes et état de montage. Les défaillances de stockage gaspillent des heures parce qu’elles ont l’air applicatives.
  5. Une fois restauré, notez la cause racine unique, le changement déclencheur, et le garde‑fou que vous ajoutez.

Si vous ne mettez en place qu’un seul garde‑fou : faites en sorte que votre health check récupère une page WordPress dynamique et échoue si le corps est vide. Le WSOD adore se cacher derrière un « 200 OK ». Ne le laissez pas faire.

← Précédent
Lectures uniquement de métadonnées ZFS : comment le vdev spécial change la donne
Suivant →
DLSS expliqué : la plus grande astuce FPS de la décennie

Laisser un commentaire