Le WordPress d'aujourd'hui, décodé pour les développeurs

Erreurs WordPress · Erreurs PHP et écran blanc

Maximum execution time exceeded : temps d’exécution dépassé

Erreur fatale PHP

« Maximum execution time of 30 seconds exceeded » : repérez le script coupable et relevez max_execution_time (PHP, wp-config.php, nginx) sans risque.

Message affiché

Fatal error: Maximum execution time of 30 seconds exceeded

En anglais : Fatal error: Maximum execution time of 30 seconds exceeded

Réponse rapide

PHP a interrompu un script qui dépassait la durée fixée par max_execution_time (30 s par défaut). Relancez la tâche par lots, ou relevez la limite avec ini_set() dans wp-config.php ou le fichier .user.ini.

Vous lancez un import, une sauvegarde, un export ou une mise à jour, et la page se fige puis affiche une ligne du type « Fatal error: Maximum execution time of 30 seconds exceeded in /…/fichier.php on line 123 ». Parfois, rien ne s’affiche : vous obtenez un écran blanc ou la page d’erreur critique. L’erreur peut survenir sur le site public comme dans l’administration, mais elle touche surtout les opérations longues.

Elle ne signifie pas que votre site est cassé : PHP a simplement jugé qu’un script travaillait depuis trop longtemps et l’a arrêté. Il faut donc comprendre ce qui prend du temps, puis soit le rendre plus rapide ou plus court, soit relever la limite.

Ce que signifie cette erreur

Le message vient de PHP lui-même, pas de WordPress : il n’existe donc pas de traduction officielle. La directive max_execution_time fixe la durée maximale, en secondes, d’exécution d’un script. Sa valeur par défaut est de 30 secondes pour les requêtes web, et de 0 (illimité) en ligne de commande, ce qui explique qu’une tâche réussisse avec WP-CLI et échoue dans le navigateur. Quand la limite est atteinte, PHP déclenche une erreur fatale (E_ERROR).

Deux précisions utiles. D’abord, sous Linux, PHP compte le temps d’exécution du script lui-même : les attentes passées hors du script (requêtes MySQL, appels réseau, sleep()) ne sont pas décomptées, ce qui rend le message plus rare que l’on pourrait croire. Ensuite, un autre minuteur peut couper la requête avant PHP : request_terminate_timeout dans PHP-FPM, ou le délai de lecture de nginx ou d’Apache. Dans ce cas, le navigateur affiche plutôt une erreur 504 ou une erreur 502, sans le message ci-dessus.

Le cœur de WordPress connaît cette limite. Pour ses opérations lourdes, il se redonne du temps : set_time_limit( 300 ) lors de l’installation d’un paquet (wp-admin/includes/class-wp-upgrader.php) et de la mise à jour du cœur (wp-admin/includes/update-core.php), 10 minutes pour une mise à jour automatique suivie d’un test par requête de contrôle. Cela ne fonctionne que si set_time_limit() n’est pas désactivée par l’hébergeur. Comme toute erreur fatale, l’erreur peut être interceptée par le gestionnaire du cœur (wp-includes/class-wp-fatal-error-handler.php), d’où la page d’erreur critique.

La valeur appliquée à votre site est visible dans Outils > Santé du site > Info > Serveur, sous le libellé « Limite d’exécution PHP ».

Diagnostic rapide

Symptôme / constatCause probableÀ vérifier
L’erreur apparaît toujours après environ 30 secondes, sur un import, un export ou une sauvegardeTâche trop longue pour la limite par défautLe journal PHP : la ligne « Maximum execution time » indique le fichier et la ligne
Le fichier cité se trouve dans wp-content/plugins/ d’une extension préciseExtension lente ou boucle sans finDésactiver l’extension et relancer l’action
L’erreur ne se produit qu’au premier chargement d’une page après une mise à jourGénération de cache, de miniatures ou d’indexRelancer ; vider les caches ; limiter la tâche
Pas de message PHP, mais une page 502 ou 504 après 60 secondesDélai de nginx, d’Apache ou de PHP-FPM atteint avant PHPJournal d’erreurs du serveur web, request_terminate_timeout
La limite reste à 30 secondes malgré vos réglagesRéglage non pris en compte (mauvais fichier, cache de .user.ini)Santé du site > Info > Serveur, ou phpinfo()
La même tâche passe en WP-CLI mais échoue dans le navigateurLimite web seulement, illimitée en ligne de commandeUtiliser WP-CLI pour les opérations lourdes

Les causes les plus fréquentes

  1. Une opération volumineuse lancée d’un seul bloc : import de produits ou d’articles, export de commandes, régénération de miniatures, sauvegarde, migration.
  2. Une limite trop basse sur un hébergement mutualisé, souvent figée à 30 secondes, parfois moins.
  3. Un appel réseau qui attend trop longtemps : API externe lente, serveur de licences injoignable, mise à jour à distance (voir la fiche cURL error 28).
  4. Une requête SQL lourde ou une boucle PHP sans fin dans une extension ou un thème, par exemple un WP_Query sans limite sur une grosse base.
  5. Une tâche planifiée trop gourmande, déclenchée par WP-Cron lors d’une visite et exécutée dans la requête d’un visiteur.
  6. Un site mal dimensionné : base surchargée, absence de cache d’objets, serveur partagé saturé.

Solutions pas à pas

Par précaution, faites une sauvegarde des fichiers et de la base avant de modifier la configuration. Du moins invasif au plus technique :

1. Identifier le script coupable

Le message donne le chemin du fichier et le numéro de ligne où PHP a été interrompu. Ce n’est pas forcément la cause du ralentissement, mais le dossier (plugins/…, themes/…) désigne l’extension ou le thème en jeu. Activez le journal dans wp-config.php, au-dessus de la ligne « That’s all, stop editing! » :

define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
define( 'WP_DEBUG_DISPLAY', false );

Relancez l’action, puis lisez la fin du journal :

tail -n 30 wp-content/debug.log

Notre article sur les bons réflexes avec WP_DEBUG_LOG détaille cette méthode. Supprimez ces lignes une fois le diagnostic terminé.

2. Découper ou relancer la tâche

Le plus sûr est de ne pas dépendre d’une longue requête. La plupart des outils d’import et de sauvegarde proposent de traiter les éléments par lots : réduisez le nombre de lignes par passage. Pour une opération sans interface, utilisez WP-CLI, qui n’est pas soumis à la limite web :

wp cron event list
wp cron event run --due-now
wp media regenerate --yes

Un cas réel avec un export de boutique est analysé dans l’article Fatal error: Maximum execution time exceeded pendant un export WooCommerce. La commande wp media regenerate nécessite que WP-CLI soit installé ; elle remplace les miniatures, faites donc une sauvegarde au préalable.

3. Relever la limite depuis WordPress

Si votre hébergeur le permet, wp-config.php est le moyen le plus simple. Placez la ligne au-dessus de « That’s all, stop editing! » :

@ini_set( 'max_execution_time', '300' );

La directive est modifiable à l’exécution, mais l’hébergeur peut désactiver ini_set(). Dans ce cas, passez par l’une des solutions suivantes. Pour un seul traitement (dans votre propre extension), appelez plutôt set_time_limit( 300 ); juste avant la boucle lourde : le compteur repart de zéro.

4. Modifier la configuration PHP

Selon votre hébergement, utilisez l’un de ces emplacements. Avec PHP en mode FastCGI ou FPM, créez ou complétez un fichier .user.ini à la racine du site (PHP le relit toutes les 5 minutes environ, patientez avant de tester) :

max_execution_time = 300

Avec Apache et le module PHP (mod_php), vous pouvez écrire dans .htaccess :

<IfModule mod_php.c>
    php_value max_execution_time 300
</IfModule>

Ne placez jamais php_value hors d’un bloc IfModule si PHP tourne en FPM : Apache ne comprend pas la directive et renvoie une erreur 500. Sur un serveur dont vous avez la main, éditez le php.ini ou le pool PHP-FPM du site :

; /etc/php/8.2/fpm/pool.d/monsite.conf (adaptez la version de PHP)
php_admin_value[max_execution_time] = 300
request_terminate_timeout = 300s

Rechargez ensuite le service (sudo systemctl reload php8.2-fpm, selon votre version). Sur un mutualisé, le réglage se trouve souvent dans le panneau de l’hébergeur, rubrique « PHP » ou « Options PHP ».

5. Aligner les délais du serveur web

Relever la limite PHP ne sert à rien si nginx ou Apache coupent avant. Avec nginx, dans le bloc location ~ \.php$ :

fastcgi_read_timeout 300s;

Avec Apache et mod_proxy_fcgi, ajoutez dans le vhost une directive comme ProxyTimeout 300. Contrôlez la syntaxe puis rechargez : sudo nginx -t && sudo systemctl reload nginx ou sudo apachectl configtest. Si vous voyez encore une page 504, lisez la fiche 504 Gateway Timeout ; l’article 504 sur un import volumineux explique le cas d’un proxy en amont.

6. Traiter la cause plutôt que le symptôme

Si une action simple demande plus de 30 secondes, le vrai problème est ailleurs. Activez le slowlog de PHP-FPM (directives request_slowlog_timeout et slowlog du pool) pour obtenir la pile d’appels des requêtes lentes, installez Query Monitor pour repérer les requêtes SQL coûteuses, et plafonnez les délais de vos appels sortants (argument timeout de wp_remote_get()). Déplacez les tâches longues dans de vraies tâches de fond plutôt que dans la requête d’un visiteur : voir les pièges classiques de WP-Cron.

Sans accès à l’administration

Modifiez wp-config.php ou .user.ini par SFTP ou depuis le gestionnaire de fichiers de l’hébergeur, ou utilisez WP-CLI en SSH. Si une extension bloque tout, renommez son dossier dans wp-content/plugins/ (par exemple en ajoutant .off) pour la désactiver, ou lancez wp plugin deactivate nom-de-l-extension.

Prévenir l’erreur

  • Traitez les gros volumes par lots et préférez WP-CLI pour les imports, exports et régénérations.
  • Testez les opérations lourdes sur un double du site avec des données réelles avant de les lancer en production.
  • Surveillez les tâches planifiées et désactivez celles qui ne servent plus ; envisagez un vrai cron système à la place de WP-Cron.
  • Fixez des délais sur tous les appels sortants pour qu’une API lente ne bloque pas une page entière.
  • Choisissez un hébergement dimensionné à votre trafic, avec un cache d’objets si votre site est dynamique.

Questions fréquentes

Peut-on mettre max_execution_time à 0 pour supprimer la limite ?

Techniquement oui, mais c’est déconseillé : un script qui boucle monopolise alors un processus PHP indéfiniment et peut saturer le serveur. Préférez une valeur large (300 ou 600) pour les besoins ponctuels.

J’ai mis 300 secondes, mais l’erreur indique toujours 30. Pourquoi ?

Le réglage n’est pas pris en compte : mauvais fichier, ini_set() désactivé, ou .user.ini mis en cache pendant quelques minutes. Contrôlez la valeur réelle dans Santé du site > Info > Serveur.

Quelle différence avec une erreur 504 ?

L’erreur « Maximum execution time » est produite par PHP. Une erreur 504 est renvoyée par le serveur web ou un proxy qui n’a pas reçu de réponse à temps. Les deux peuvent se combiner, il faut alors relever les deux limites.

Ma mise à jour de WordPress ou d’une extension s’est interrompue. Est-ce grave ?

Relancez-la. Si le site affiche « Brièvement indisponible », consultez la fiche maintenance bloquée pour supprimer le fichier .maintenance.