Le code 502 Bad Gateway signifie que le serveur qui fait office de passerelle ou de proxy a reçu une réponse invalide du serveur situé en amont. La requête est sortie du proxy. Ce qui est revenu n’est pas une réponse HTTP utilisable : connexion refermée trop tôt, tampon vide, ou en-têtes que le proxy refuse. Le visiteur voit la page du proxy (Nginx, load balancer, parfois Cloudflare qui relaie un 502 d’origine). L’application, elle, n’a pas rendu une page.
Ce n’est pas un 500 écrit par PHP, et ce n’est pas un délai où le proxy attend encore.
Quand un 502 apparaît
- PHP-FPM accepte la requête puis meurt. Le journal Nginx contient « upstream prematurely closed connection » ou « recv() failed ». Causes fréquentes : saturation mémoire du processus, extension native qui segfault, ou le tueur OOM du système.
- Le socket ou le port d’amont est faux.
fastcgi_passpointe vers un fichier de socket qui n’est plus celui de PHP-FPM. Le proxy se connecte à quelque chose qui ne parle pas FastCGI. - L’amont renvoie des en-têtes trop gros. Nginx journalise « upstream sent too big header ». Des cookies empilés ou une redirection avec une requête énorme dépassent
fastcgi_buffer_size. - Le service d’amont redémarre pendant la requête. Les appels en cours reçoivent une coupure, les suivants repassent.
- Un proxy en chaîne relaie un 502 déjà produit plus bas. Il faut lire le journal du premier proxy, pas seulement celui du CDN.
Le test utile consiste à appeler l’amont sans le proxy, sur le port ou le socket local, avec le bon en-tête Host. S’il répond correctement en direct et 502 via le proxy, la faute est le lien entre les deux.
Lire la phrase du journal
- Reproduisez une URL. Notez la seconde.
- Dans le journal d’erreurs du proxy, copiez la phrase. « prematurely closed », « connect() failed », « too big header » et « upstream timed out » ne se corrigent pas de la même façon. La dernière est un 504, même si une page personnalisée mélange les textes.
- Regardez si PHP-FPM a redémarré au même instant (journal système,
oom-kill). - Appelez l’amont en direct. S’il répond 500 avec une erreur PHP, vous n’êtes plus sur un 502 : le proxy montrait seulement que la réponse était déjà cassée, ou il masquait le corps.
- Depuis l’extérieur, un test d’URL confirme que le 502 n’est pas limité à votre navigateur.
Les fonctionnalités de surveillance d’une URL précise servent ici : la page d’accueil en cache peut rester en 200 pendant que l’URL dynamique, seule à interroger PHP, répond 502.
Réparer l’amont
| Phrase du journal | Correction |
|---|---|
| prematurely closed / OOM | Relever la mémoire du pool seulement après avoir trouvé la requête qui tue le processus. Limiter pm.max_children si le serveur swap |
| connect() failed, socket | Aligner fastcgi_pass sur le socket réellement ouvert par PHP-FPM |
| upstream sent too big header | Augmenter les tampons FastCGI, et réduire les cookies qui gonflent les en-têtes |
| 502 seulement au redémarrage | Terminer le déploiement quand le pool est de nouveau prêt. Éviter de couper le service aux heures de commande |
| 502 hérité d’un autre proxy | Corriger le proxy qui produit le code, pas celui qui le relaie |
Rechargez la configuration, puis retestez l’URL sans cache. Un 200 direct vers PHP-FPM et un 502 public veulent dire que le proxy pointe encore au mauvais endroit.
Ce qu’il ne faut pas faire
N’allongez pas le délai de lecture du proxy : un 502 revient souvent tout de suite, parce que la réponse est mauvaise, pas lente. Ne désactivez pas le proxy pour « tester en production » sans remettre la même configuration ensuite. Ne confondez pas avec une maintenance : si vous coupez volontairement l’origine, annoncez-le en 503 avec Retry-After, au lieu de laisser le proxy inventer un 502.
Contrôlez l’URL publique après correction, pas seulement 127.0.0.1. C’est le même principe que pour tester si un site répond vraiment : le code vu par un client extérieur.
