Nginx

502 Bad Gateway

Nginx responde y funciona. Lo que falla es lo que hay detrás: la aplicación a la que hace de proxy no contesta, contesta mal o no deja conectar.

El 502 lo genera Nginx, así que la causa está en su error_log, no en el del navegador. Esa línea dice exactamente qué ha pasado y ahorra todo lo demás.

Qué comprobar, y en qué orden

En el orden en que lo miramos nosotros. No es un ranking de frecuencia: no publicamos estadísticas que no hemos medido.

  1. 1

    La aplicación no está corriendo.

    Comprobar

    sudo tail -20 /var/log/nginx/error.log
    sudo systemctl status mi-aplicacion

    Corregir

    sudo systemctl start mi-aplicacion
  2. 2

    Escucha en otro puerto o en otra dirección que la del proxy_pass. Una aplicación que escucha en 127.0.0.1 no es accesible si Nginx apunta a otra IP, y al revés.

    Comprobar

    sudo ss -tlnp | grep -E ':(3000|8000|8080|9000)'
    grep -r proxy_pass /etc/nginx/

    Corregir

    # Alinear proxy_pass con lo que muestre ss, y después:
    sudo nginx -t && sudo systemctl reload nginx
  3. 3

    Con PHP-FPM, el socket no existe o Nginx no puede leerlo. En el log sale «connect() to unix:... failed (2: No such file or directory)» o un 13 de permiso denegado.

    Comprobar

    sudo ss -xl | grep php
    ls -l /run/php/

    Corregir

    sudo systemctl restart php8.2-fpm
    # Si es de permisos, alinear listen.owner y listen.group del pool con el usuario de Nginx.
  4. 4

    La aplicación tarda más que proxy_read_timeout. En el log sale «upstream timed out».

    Comprobar

    sudo grep 'upstream timed out' /var/log/nginx/error.log | tail -5

    Corregir

    # En el bloque location:
    #   proxy_read_timeout 120s;
    # Subirlo es un parche: lo que corresponde es averiguar por qué tarda tanto.
  5. 5

    SELinux impide que Nginx abra conexiones de red. Solo en RHEL, Rocky y AlmaLinux; en el log sale un 13 de permiso denegado hacia el upstream.

    Comprobar

    sudo getenforce
    sudo ausearch -m avc -ts recent 2>/dev/null | grep nginx | tail -5

    Corregir

    sudo setsebool -P httpd_can_network_connect 1
  6. 6

    La aplicación se está quedando sin memoria y el kernel la mata. El 502 va y viene sin patrón claro.

    Comprobar

    sudo dmesg -T | grep -i 'killed process' | tail -5

    Corregir

    # Ajustar el límite de memoria del servicio o el número de workers.
    # journalctl -u mi-aplicacion muestra los reinicios que provoca.

Un detalle que ahorra tiempo

Ese curl desde el propio servidor separa los dos mundos: si responde, el problema está entre Nginx y la aplicación —configuración, socket, SELinux—; si no responde, el problema es la aplicación y Nginx solo está informando.

Los comandos de esta página se ejecutan en tu servidor y algunos modifican la configuración: léelos antes de pegarlos. Las rutas y los nombres de servicio varían entre distribuciones. Así se elabora este catálogo.