cURL error 28: Operation timed out after 5001 milliseconds : ce message d’erreur, retrouvé dans les journaux d’un plugin qui appelle une API de génération de texte, revient si souvent qu’il mérite un article à lui seul. La cause est presque toujours la même, et la correction tient en une ligne.
La fonction wp_remote_post(), utilisée par la grande majorité des extensions WordPress pour dialoguer avec une API externe, applique par défaut un délai d’expiration de cinq secondes. Ce délai convient parfaitement à un appel classique vers une API de paiement ou de géolocalisation, mais devient rapidement insuffisant face à un modèle de langage qui peut mettre dix, vingt, parfois trente secondes à produire une réponse complète, en particulier sur un texte long.
Le paramètre en cause
Le paramètre timeout de wp_remote_post() s’exprime en secondes et se transmet dans le tableau d’arguments de la fonction. Voici l’appel corrigé pour un appel de génération de texte typique :
$reponse = wp_remote_post( 'https://api.fournisseur-llm.example/v1/completions', array(
'timeout' => 60,
'headers' => array(
'Authorization' => 'Bearer ' . MON_PROJET_LLM_API_KEY,
'Content-Type' => 'application/json',
),
'body' => wp_json_encode( array(
'prompt' => $prompt,
'max_tokens' => 800,
) ),
) );
if ( is_wp_error( $reponse ) ) {
error_log( 'Appel LLM echoue : ' . $reponse->get_error_message() );
return new WP_Error( 'llm_indisponible', 'Le service de generation est momentanement indisponible.' );
}
Un délai de soixante secondes couvre la majorité des cas pour un texte de longueur raisonnable, mais ce chiffre reste à ajuster selon le fournisseur choisi et le volume de texte demandé.

Pourquoi ne pas simplement mettre un délai très long
Augmenter le délai d’expiration à cinq minutes « pour être tranquille » crée un autre problème : si l’appel se produit de façon synchrone pendant le chargement d’une page d’administration, l’utilisateur reste bloqué face à un écran figé pendant toute la durée de l’attente, sans retour visuel. Un délai trop généreux transforme un problème de fiabilité réseau en un problème d’expérience utilisateur.
Les variantes selon le fournisseur
- Pour un appel de génération de texte court, un délai de 30 secondes suffit généralement.
- Pour un appel de génération de texte long ou de résumé d’un document volumineux, prévoir 60 à 90 secondes.
- Pour un appel de génération d’image, souvent plus lent, certains fournisseurs recommandent un délai supérieur à 120 secondes, ce qui rend un traitement asynchrone via WP-Cron ou Action Scheduler préférable à un appel bloquant.
Le filtre à connaître pour un ajustement global
Le filtre http_request_timeout permet d’ajuster la valeur par défaut de façon centralisée, plutôt que de la répéter dans chaque appel du plugin :
add_filter( 'http_request_timeout', function( $timeout ) {
return 60;
} );
Ce filtre s’applique à l’ensemble des appels HTTP de WordPress passant par l’API HTTP native, y compris ceux d’autres extensions actives sur le site : à utiliser avec prudence sur un site où plusieurs plugins effectuent des appels réseau de nature différente.
Le réflexe qu’on applique désormais systématiquement : ne jamais laisser le délai d’expiration par défaut sur un appel de génération de texte, et toujours prévoir un traitement asynchrone dès que l’appel dépasse trente secondes en moyenne.
En résumé
Le message cURL error 28 n’indique presque jamais un problème de réseau ponctuel : il signale un délai d’expiration mal calibré pour le type d’appel effectué. Ajuster le paramètre timeout selon le fournisseur et la nature de la requête, plutôt que de le régler au hasard, évite la majorité des échecs silencieux observés sur ce type d’intégration.
Un dernier point mérite d’être vérifié une fois le délai correctement ajusté : la configuration du serveur d’hébergement lui-même. Certaines configurations imposent un délai maximal d’exécution PHP, réglé via la directive max_execution_time, qui peut interrompre le script avant même que le délai fixé dans wp_remote_post() ne soit atteint. Un timeout de soixante secondes sur l’appel réseau ne sert à rien si le script PHP lui-même est arrêté au bout de trente secondes par la configuration du serveur.
Vérifier cette cohérence entre les deux réglages, réseau et exécution PHP, évite un débogage frustrant où l’erreur observée ne correspond à aucun des deux délais configurés explicitement dans le code du plugin.