502 Bad Gateway: cosa si è rotto dietro il proxy e come trovarlo
Un 502 Bad Gateway significa che un proxy davanti al tuo sito ha chiesto una risposta al backend e ha ottenuto qualcosa di non valido, o niente affatto. Il proxy funziona correttamente; sta riportando che qualunque cosa stia dietro di esso è giù, sta andando in crash, o parla il protocollo sbagliato.
Chi restituisce un 502 e perché
RFC 9110 definisce il 502 per un server che agisce come gateway o proxy e ha ricevuto una risposta non valida da un server in entrata a cui ha avuto accesso mentre cercava di soddisfare la richiesta. Ogni stack moderno ha almeno un salto di questo tipo: nginx o Apache davanti a un application server, un load balancer davanti a una flotta, una CDN davanti alla tua origine, o tutti e tre.
Questa stratificazione è la chiave per leggere un 502. Il componente che ha risposto è abbastanza sano da generare una pagina di errore. Il componente dietro di esso non lo è. Quindi un 502 divide sempre il tuo stack in una metà funzionante e una rotta, e il tuo compito è capire dov'è il confine.
I suoi vicini dicono qualcosa di più circoscritto. Un 504 Gateway Timeout significa che il backend era raggiungibile ma troppo lento. Un 500 significa che il backend stesso ha girato e ha sollevato un errore. Un 502 significa che il backend ha dato una risposta cattiva o nessuna risposta affatto. Il confronto completo è nella panoramica 5xx.
Cause comuni
- Il processo backend non è in esecuzione. Un application server crashato, un pool PHP-FPM fermato, un container uscito o che ha fallito il suo health check. Il proxy si connette a una porta su cui nessuno è in ascolto.
- Il backend è crashato a metà richiesta. Un kill per esaurimento memoria o un segmentation fault chiude la connessione prima che gli header della risposta siano completi.
- Indirizzo o porta upstream sbagliati. Una configurazione che punta alla vecchia porta dopo una modifica, o a un host che non risolve più.
- Discordanza di protocollo. Il proxy parla HTTP semplice a una porta che si aspetta TLS, o viceversa. I byte non sono analizzabili, quindi il proxy dichiara la risposta non valida.
- Header di risposta troppo grandi. Un cookie sovradimensionato o un header insolitamente lungo supera il buffer del proxy, e la risposta viene rifiutata invece che passata.
- Discordanza keep-alive. Il proxy riusa una connessione inattiva che il backend ha già chiuso, producendo 502 sporadici sotto un carico altrimenti normale.
- Riavvii e deploy. Qualsiasi finestra in cui il vecchio processo si è fermato e quello nuovo non accetta ancora connessioni.
- Tutti i backend non sani. Un load balancer senza membri funzionanti non ha dove inviare la richiesta.
Leggere il log del proxy, che di solito conclude l'indagine
Il codice di stato è generico, ma la riga di log del proxy è specifica. Con nginx, questi sono i messaggi che vale la pena riconoscere:
[error] connect() failed (111: Connection refused) while connecting to upstream,
upstream: "http://127.0.0.1:8080/"
[error] upstream prematurely closed connection while reading response header
from upstream
[error] recv() failed (104: Connection reset by peer) while reading response
header from upstream
[error] upstream sent too big header while reading response header from upstream
[error] no live upstreams while connecting to upstream
Ognuno punta a qualcosa di diverso:
connect() failed (111: Connection refused). Nessuno è in ascolto su quell'indirizzo e porta. Il backend è fermato, legato a un'interfaccia diversa, o su una porta diversa da quella indicata dalla configurazione.upstream prematurely closed connection. Il backend ha accettato la richiesta e poi è morto o si è bloccato prima di finire la risposta. Cerca crash, kill per esaurimento memoria o un timeout del worker dentro l'applicazione, non su nginx.connection reset by peer. Simile, ma la connessione è stata resettata attivamente. Spesso un firewall nel mezzo, o un backend che ha chiuso una connessione in pool che il proxy considerava ancora aperta.upstream sent too big header. Un problema di dimensione del buffer nel proxy, non un guasto nel backend. La risposta è valida ma più grande di quanto il proxy sia configurato per contenere.no live upstreams. Gli health check hanno segnato tutti i backend come giù.
Come risolverlo
- Testa il backend direttamente, bypassando il proxy. Dall'host del proxy, richiedi l'indirizzo upstream stesso:
Un 200 qui con un 502 sull'URL pubblico significa che il guasto è nella configurazione del proxy o nel collegamento tra i due. Una connessione rifiutata significa che il backend è davvero giù.curl -sS -o /dev/null -w "%{http_code}\n" http://127.0.0.1:8080/ - Controlla che il backend sia in esecuzione e in ascolto sull'indirizzo atteso dal proxy. Legarsi a
127.0.0.1quando il proxy contatta un indirizzo di container è una causa frequente. - Leggi il log degli errori del proxy e associa il messaggio all'elenco sopra prima di cambiare qualsiasi configurazione.
- Poi leggi il log del backend. Un crash, un kill per esaurimento memoria o un timeout del worker nello stesso secondo conferma il caso "prematurely closed". Il silenzio riporta invece alla connettività.
- Verifica indirizzo, porta e schema upstream nella configurazione del proxy, specialmente dopo una migrazione o una ricostruzione del container.
- Alza i buffer degli header del proxy se il log dice che l'header era troppo grande, e separatamente scopri perché l'header è cresciuto.
- Fai sovrapporre i deploy. Avvia il nuovo processo, attendi che superi un health check, poi svuota e ferma quello vecchio. Gli aggiornamenti rolling con gate di salute eliminano del tutto la finestra di riavvio che causa i 502 durante il deploy.
Intercettare un 502 che dura venti secondi
I 502 al momento del deploy e da crash-loop sono brevi. Un backend riparte, dà errore per venti secondi e si riprende, quindi quando qualcuno controlla il sito va bene e non resta nulla da vedere. Un controllo HTTP pianificato in esecuzione continua registra quelle finestre con timestamp, il che trasforma "stamattina era strano per un attimo" in un pattern che puoi correlare con deploy e riavvii. Un 502 può anche provenire da un edge CDN invece che dalla tua origine, quindi controllare da diverse regioni distingue un fallimento globale del backend da un problema di edge che colpisce solo parte del tuo traffico, ed è a questo che serve il monitoraggio della disponibilità distribuito.