Solución de Errores Comunes de Nginx: Una Guía Práctica

¿Encuentras errores de Nginx? Esta guía práctica te ayuda a diagnosticar y resolver problemas comunes. Aprende a abordar problemas de configuración, errores de permiso denegado, conexión rechazada, errores de puerta de enlace 502/504 y más. Proporcionamos explicaciones claras, soluciones prácticas y comandos esenciales de Nginx para mantener tu sitio accesible y funcionando sin problemas.

Solución de Errores Comunes de Nginx: Una Guía Práctica

Solucionar errores comunes de Nginx se vuelve mucho más fácil cuando dejas de tratar el código de estado como el problema completo. Un 502 podría ser una aplicación bloqueada, una ruta de socket incorrecta o un backend que devolvió encabezados rotos. Un 403 podría ser permisos de archivo, un archivo de índice faltante o una regla de denegación que coincidió con más de lo que esperabas.

Comienza con la evidencia: el registro de errores, el registro de acceso, nginx -t y los registros del backend si Nginx está actuando como proxy para una aplicación. Adivinar solo desde la página del navegador pierde tiempo.

Comienza con las Comprobaciones Rápidas

Ejecuta estos comandos antes de cambiar la configuración:

sudo nginx -t
sudo systemctl status nginx --no-pager
sudo tail -n 80 /var/log/nginx/error.log
sudo tail -n 80 /var/log/nginx/access.log

nginx -t te indica si la configuración se puede analizar. El estado del servicio te indica si Nginx se está ejecutando. Los registros te indican lo que Nginx vio al manejar la solicitud.

Si el problema está vinculado a una URL, reprodúcelo con curl para que puedas ver los encabezados y el estado claramente:

curl -I https://ejemplo.com/ruta/del/problema
curl -v https://ejemplo.com/ruta/del/problema

Si el problema solo ocurre para un nombre de host específico, inclúyelo:

curl -I -H 'Host: app.ejemplo.com' http://127.0.0.1/

Eso separa el enrutamiento de Nginx del comportamiento de DNS, CDN y balanceador de carga.

Nginx No Inicia o No se Recarga

Una falla de inicio generalmente es un error de sintaxis, una directiva duplicada en el contexto incorrecto, un archivo de inclusión faltante o un problema con la ruta del certificado.

Usa:

sudo nginx -t
sudo journalctl -u nginx -n 100 --no-pager

Los mensajes comunes son directos:

  • unknown directive significa un error tipográfico, un módulo no compatible o una directiva colocada en la compilación incorrecta de Nginx.
  • directive is not allowed here significa que la directiva está en el contexto incorrecto, como poner una directiva solo de http dentro de server.
  • cannot load certificate significa que la ruta es incorrecta, el archivo falta o los permisos impiden que Nginx lo lea.
  • bind() to 0.0.0.0:80 failed a menudo significa que otro proceso ya está usando el puerto.

Verifica los puertos con:

sudo ss -tulnp | grep ':80\|:443'

No recargues hasta que nginx -t pase. Una recarga fallida generalmente mantiene el proceso de trabajo antiguo en ejecución, pero un reinicio fallido puede dejar el sitio fuera de servicio.

(13: Permission denied) y 403 Forbidden

Permission denied aparece en el registro de errores cuando el usuario trabajador de Nginx no puede leer un archivo o atravesar un directorio. Un navegador puede ver 403 Forbidden.

Primero encuentra el usuario trabajador:

grep -R '^user ' /etc/nginx/nginx.conf

En Debian y Ubuntu suele ser www-data. En sistemas compatibles con RHEL suele ser nginx.

Para una raíz estática como /var/www/html, Nginx necesita permiso de ejecución en cada directorio padre y permiso de lectura en el archivo:

sudo find /var/www/html -type d -exec chmod 755 {} \;
sudo find /var/www/html -type f -exec chmod 644 {} \;

Evita ejecutar chown -R www-data:www-data en directorios de aplicaciones de forma refleja. Puede hacer que el error desaparezca mientras le das al servidor web acceso de escritura que no necesita. Un patrón más seguro es mantener la propiedad de implementación separada y otorgar a Nginx acceso de lectura.

Si los permisos se ven bien, verifica si la solicitud es para un directorio sin archivo de índice:

location / {
    root /var/www/html;
    index index.html index.htm;
}

Si /docs/ no tiene index.html y autoindex está desactivado, Nginx devuelve 403. Eso es un comportamiento correcto.

SELinux también puede causar fallas de estilo de permisos en sistemas de la familia RHEL. Si los permisos de archivo son correctos pero Nginx aún no puede leer o actuar como proxy, verifica los registros de auditoría antes de deshabilitar SELinux:

sudo ausearch -m avc -ts recent

(111: Connection refused) y 502 Bad Gateway

Connection refused significa que Nginx intentó conectarse a un upstream y el objetivo lo rechazó activamente. La aplicación puede estar caída, escuchando en una dirección diferente o usando una ruta de socket que no existe.

Para este proxy:

location / {
    proxy_pass http://127.0.0.1:3000;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
}

verifica:

sudo ss -tulnp | grep 3000
curl -I http://127.0.0.1:3000
sudo systemctl status tu-app --no-pager

Si Nginx usa un socket Unix, verifica el archivo del socket:

ls -l /run/gunicorn/app.sock

El usuario trabajador debe poder leer y escribir el socket.

Un 502 Bad Gateway es más amplio. Nginx alcanzó algo upstream, pero la respuesta no era válida, estaba incompleta, se cerró demasiado pronto o no era lo que Nginx esperaba. Verifica los registros de la aplicación en la misma marca de tiempo que el error de Nginx. Esa coincidencia de marca de tiempo es importante; de lo contrario, terminarás persiguiendo la excepción de ayer.

Para PHP-FPM, verifica que fastcgi_pass coincida con el socket o puerto del pool configurado. Por ejemplo:

fastcgi_pass unix:/run/php/php8.3-fpm.sock;

Luego verifica:

sudo systemctl status php8.3-fpm --no-pager
ls -l /run/php/php8.3-fpm.sock

504 Gateway Timeout

Un 504 significa que Nginx esperó al upstream y no recibió una respuesta oportuna. Aumentar los tiempos de espera puede ser válido para informes, importaciones u operaciones de administración lentas, pero no debería ser la única solución para un punto final público que es lento en cada solicitud.

location /api/reports/ {
    proxy_pass http://127.0.0.1:3000;
    proxy_connect_timeout 10s;
    proxy_send_timeout 60s;
    proxy_read_timeout 180s;
}

Luego mira el tiempo del backend. Agrega el tiempo upstream a los registros de acceso si aún no lo tienes:

log_format proxy_timing '$remote_addr "$request" $status '
                        'request_time=$request_time '
                        'upstream_time=$upstream_response_time';

Si $upstream_response_time es alto, la aplicación o la base de datos probablemente son el punto de enfoque. Si Nginx muestra tiempos de espera pero los registros de la aplicación dicen que respondió rápidamente, verifica los saltos de red, la red de contenedores, la resolución de DNS dentro del host o un balanceador de carga entre Nginx y la aplicación.

413 Request Entity Too Large

413 generalmente es directo: el cuerpo de la solicitud es más grande de lo que permite Nginx. Las cargas, las cargas útiles JSON grandes y las publicaciones de formularios pueden desencadenarlo.

Establece client_max_body_size en el lugar más estrecho útil:

server {
    server_name ejemplo.com;

    location /upload/ {
        client_max_body_size 100M;
        proxy_pass http://127.0.0.1:3000;
    }
}

Establecer un límite global enorme rara vez es una buena idea. La mayoría de las rutas no lo necesitan, y los cuerpos permitidos más grandes aumentan la cantidad de trabajo que un cliente malo puede forzar en tu pila.

Errores de SSL y Certificados

Las fallas de TLS a menudo se ven diferentes dependiendo de dónde las notes. Nginx puede fallar al recargar, los navegadores pueden advertir sobre el certificado o los clientes pueden fallar en un handshake.

Verifica las fechas del certificado:

openssl x509 -in /etc/letsencrypt/live/ejemplo.com/fullchain.pem -noout -dates -subject -issuer

Verifica lo que presenta el servicio público:

openssl s_client -connect ejemplo.com:443 -servername ejemplo.com </dev/null 2>/dev/null | openssl x509 -noout -dates -subject -issuer

Si esos dos comandos muestran certificados diferentes, un balanceador de carga, CDN o un host diferente puede estar sirviendo tráfico.

400 Bad Request y Problemas de Encabezados

400 generalmente significa que Nginx no aceptó la sintaxis de la solicitud. Con navegadores reales es menos común, pero los bots, clientes antiguos, proxies inusuales o encabezados de gran tamaño pueden causarlo.

Busca mensajes como client sent too large request header. Si una cookie de SSO o aplicación legítima es demasiado grande, es posible que debas ajustar la configuración del búfer de encabezados. Trata eso como una solución específica, no como una primera respuesta. Las cookies de gran tamaño a menudo se solucionan mejor en la aplicación.

Un Orden Práctico de Operaciones

Cuando un problema de Nginx está activo, usa un orden repetible:

  1. Confirma la URL exacta, el host, el código de estado y la hora.
  2. Verifica nginx -t y el estado del servicio.
  3. Coincide la solicitud en el registro de acceso.
  4. Coincide la misma marca de tiempo en el registro de errores.
  5. Si está actuando como proxy, verifica el estado y los registros del servicio upstream.
  6. Prueba el upstream directamente desde el host de Nginx.
  7. Realiza el cambio de configuración más pequeño que se ajuste a la evidencia.
  8. Ejecuta nginx -t, recarga y observa los registros mientras vuelves a probar.

La mayoría de los problemas de Nginx se vuelven ordinarios una vez que sabes dónde ocurrió la falla: antes de Nginx, dentro de Nginx, entre Nginx y el upstream, o dentro del servicio upstream.