Objetivos de aprendizaje
Después de leer este artículo podrás:
- Distinguir 500, 502, 503 y 504 a partir del síntoma exacto
- Encontrar la causa en los logs de la app y del proxy
- Corregir las causas más comunes y evitar que vuelvan
En esta página
- ¿Qué significa cada código 5xx?
- ¿Por qué recibo un 500 Internal Server Error?
- ¿Por qué recibo un 502 Bad Gateway?
- ¿Por qué recibo un 503 Service Unavailable?
- ¿Por qué recibo un 504 Gateway Timeout?
- ¿Cómo diagnosticar un error 5xx paso a paso?
- ¿Cómo evitar los errores 5xx?
- Cómo hacerlo en Square Cloud
- Preguntas frecuentes
Todos los códigos de estado del 500 al 599 dicen lo mismo: la petición era válida, pero el servidor no pudo completarla. El visitante no hizo nada mal, y la solución está de tu lado. Los cuatro códigos que más vas a ver se parecen en el navegador, pero apuntan a lugares muy distintos de la cadena de la petición.
El truco es averiguar quién generó el error. Una página escueta de "500 Internal Server Error" que viene de tu framework significa que falló tu código. Una página "502 Bad Gateway" simple, o con la marca de nginx, de una CDN o de un balanceador de carga, significa que el proxy que está delante de tu app se queja de la app.
¿Qué significa cada código 5xx?#
| Código | Nombre | Lo genera | Qué significa |
|---|---|---|---|
| 500 | Internal Server Error | La app | Una condición inesperada impidió que la app respondiera |
| 502 | Bad Gateway | Un proxy o gateway | Recibió una respuesta inválida del servidor de origen |
| 503 | Service Unavailable | La app o el proxy | No puede atender la petición por ahora (sobrecarga o mantenimiento) |
| 504 | Gateway Timeout | Un proxy o gateway | No recibió a tiempo la respuesta del servidor de origen |
Estas definiciones vienen del RFC 9110, sección 15.6. La distinción que importa: 502 y 504 solo los genera algo que está entre el visitante y tu app. Sin nada delante de tu app, rara vez los verás, salvo que tu propio código actúe como gateway hacia otro servicio.
¿Por qué recibo un 500 Internal Server Error?#
El 500 es el código genérico. Tu código lanzó una excepción que nadie manejó, y el framework respondió con 500. El navegador no te dice nada útil; el log te lo dice todo.
Causas comunes, de la más a la menos frecuente:
- Una excepción no manejada: leer una propiedad de
undefined, un JSON que no se pudo parsear, un campo que falta. - Una dependencia que falla: la base de datos no responde, las credenciales son incorrectas, una API de terceros superó el tiempo de espera.
- Una variable de entorno o un archivo de configuración que existe en tu máquina, pero no en producción.
- Quedarse sin memoria, lo que mata el proceso en mitad de la petición.
- Un deploy defectuoso: un módulo que falta o un build que no terminó.
Para diagnosticarlo, reproduce la petición y lee el stack trace en los logs de la app. Después asegúrate de que los errores se capturen y se registren en lugar de llegar al visitante:
import express from "express";
const app = express();
app.get("/users/:id", async (req, res) => {
const user = await findUser(req.params.id); // puede lanzar una excepción
if (!user) return res.status(404).json({ error: "not found" });
res.json(user);
});
// Express 5 envía aquí las promesas rechazadas de los handlers async
app.use((err, req, res, next) => {
console.error(`${req.method} ${req.url}`, err);
res.status(500).json({ error: "internal error" });
});
app.listen(process.env.PORT ?? 3000, "0.0.0.0");Fíjate en el 404 para un usuario que no existe. Devolver 500 en un caso normal de "no encontrado" llena los logs y esconde los fallos reales.
¿Por qué recibo un 502 Bad Gateway?#
Un 502 significa que el proxy llamó a tu app y recibió basura, o nada. Como dice MDN, un servidor que actúa como gateway recibió una respuesta inválida del servidor de origen. En la práctica, la app casi siempre está caída o no es accesible. Revisa esto en orden:
- La app se cayó o no está corriendo. El proxy no tiene con quién hablar. Mira el proceso: ¿terminó, se reinicia en bucle o lo mataron por memoria?
- La app todavía está arrancando. Justo después de un deploy o un reinicio, el puerto aún no está abierto. Los arranques lentos (migraciones, carga de modelos grandes) alargan este intervalo.
- Puerto o dirección incorrectos. El proxy reenvía al puerto 3000, pero la app escucha en el 8080. O la app se enlaza a
127.0.0.1dentro de un contenedor, así que nada de fuera la alcanza. Enlázala a0.0.0.0y lee el puerto del entorno. - La app cerró la conexión en mitad de la respuesta, por ejemplo por un fallo durante una petición o un timeout de keep-alive más corto que el del proxy.
- Una regla del proxy apunta al origen equivocado, como una errata en un
proxy_passo una dirección de backend obsoleta.
Si la app funciona cuando abres su puerto directamente pero falla detrás del proxy, el problema está en la configuración del proxy, no en el código. Mira qué hace un proxy inverso para entender ese salto.
¿Por qué recibo un 503 Service Unavailable?#
Un 503 dice "ahora no". Según el RFC 9110, el servidor no puede atender la petición temporalmente por sobrecarga o mantenimiento programado, y puede enviar una cabecera Retry-After para indicar cuándo volver a intentarlo (sección 10.2.3).
Causas típicas:
- Todos los workers o espacios de conexión están ocupados, así que las peticiones nuevas se rechazan o se caen de la cola.
- No queda ningún backend sano: un balanceador de carga marcó todos como fallidos en los health checks.
- Un modo de mantenimiento intencionado.
- Un rate limiter o un servicio de origen que descarta carga.
Si devuelves 503 a propósito, indica cuándo volver a intentarlo, para que los rastreadores y los clientes esperen antes de reintentar:
app.use((req, res, next) => {
if (process.env.MAINTENANCE === "1") {
res.set("Retry-After", "600"); // segundos
return res.status(503).send("Volvemos en unos 10 minutos");
}
next();
});Para resolver una sobrecarga real, encuentra primero el cuello de botella: la CPU al máximo, la memoria llena, una consulta lenta que ocupa todas las conexiones. Añadir workers no ayuda si el límite es la base de datos.
¿Por qué recibo un 504 Gateway Timeout?#
Un 504 significa que el proxy se conectó a tu app, pero la app tardó demasiado en responder. La app está viva, solo que lenta. Nginx, por ejemplo, espera por defecto 60 segundos entre dos lecturas sucesivas del origen (proxy_read_timeout 60s), según la documentación del módulo proxy de nginx. Otros proxies y CDNs tienen sus propios límites, a menudo más cortos o fijos.
Causas típicas:
- Una consulta lenta a la base de datos, un índice que falta o un bloqueo.
- Una petición que llama a otra API que se cuelga, sin un timeout propio.
- Trabajo pesado dentro de la petición: procesar imágenes, generar informes, grandes exportaciones.
- Una app saturada, en la que las peticiones esperan en cola antes de ser atendidas.
La solución casi nunca es "subir el timeout del proxy". Saca el trabajo largo de la petición, responde rápido con un id de tarea y deja que el cliente consulte periódicamente o reciba un webhook. Añade timeouts explícitos a cada llamada saliente para que una dependencia colgada falle rápido con un error claro. Si de verdad necesitas un límite más largo para una ruta, súbelo solo para esa ruta. Para entender la capa que reparte las peticiones entre instancias y que también puede cortarlas, mira qué es un balanceador de carga.
¿Cómo diagnosticar un error 5xx paso a paso?#
- Identifica quién respondió. Revisa las cabeceras de la respuesta y el cuerpo de la página. Una cabecera
Servero una página de error con la marca de una CDN te dicen qué capa falló. - Lee los logs de la app en el momento del error. Un stack trace significa 500. Ni traza ni petición significa que el proxy nunca llegó a la app. La guía cómo leer los logs de tu aplicación te ayuda en este paso.
- Revisa el proceso. ¿Está corriendo, cuánto tiempo lleva activo, se reinició hace poco, cuánta memoria usa?
- Llama a la app directamente, sin pasar por el proxy, con
curl -i http://localhost:3000/health. Si funciona, mira la configuración del proxy. - Revisa las dependencias. Base de datos, caché y APIs externas. Una dependencia lenta o caída produce 500, 503 y 504 por igual.
- Mira el patrón. Una sola ruta apunta a un bug en el código. Todas las rutas apuntan a una app o un proxy caídos. Errores intermitentes bajo carga apuntan a capacidad o a timeouts.
Un endpoint /health que comprueba la base de datos y devuelve 200 o 503 ahorra tiempo aquí, y los balanceadores de carga pueden usarlo para sacar de la rotación una instancia que falla. Para una lista más amplia cuando todo el sitio está inaccesible, mira por qué mi sitio web está caído.
¿Cómo evitar los errores 5xx?#
- Registra cada error no manejado con la ruta de la petición y un id de petición.
- Pon timeouts en cada llamada a la base de datos y HTTP que haga tu app.
- Reinicia el proceso automáticamente si termina, y alerta cuando se caiga repetidamente.
- Haz pruebas de carga antes del lanzamiento para saber dónde se acaba la capacidad.
- Ejecuta las migraciones y el trabajo lento de arranque antes de que la app acepte tráfico, no durante.
- Sigue la proporción de respuestas 5xx a lo largo del tiempo. Una línea que sube te avisa antes de que se quejen los usuarios.
Cómo hacerlo en Square Cloud#
En Square Cloud, cada aplicación web corre en su propio contenedor aislado, y la investigación de un 5xx empieza igual: por los logs. Se transmiten en tiempo real en el panel, la CLI, la extensión de VS Code y la app móvil, lo que facilita ver un fallo o un stack trace justo después de que falle una petición.
Un 502 después de un deploy suele significar que la app no escucha en 0.0.0.0 en el puerto de la variable PORT, así que compruébalo primero. Los contenedores están siempre encendidos, sin cold start ni modo de suspensión, y el reinicio automático (activado por defecto en el deploy desde el panel) levanta de nuevo la aplicación que termina con error. Quedarse sin memoria es distinto: la aplicación se detiene y sigue parada hasta que subes su RAM en la configuración y la inicias de nuevo. Las aplicaciones web necesitan al menos 512 MB de RAM.
Para ver con qué frecuencia ocurren los errores, la analítica web incluida en todos los planes muestra rutas y códigos de estado, recogidos en el servidor. Los planes Pro y Enterprise añaden latencia p50, p95 y p99 y logs HTTP, útiles para encontrar las rutas lentas detrás de los 504. Tu sitio también recibe un subdominio *.squareweb.app con HTTPS, así que puedes probar la app directamente antes de conectar un dominio personalizado.
Los recursos de hosting de sitios están en la página de Sites.
Hosting de sitios web
Sitios estáticos y SSR con TLS automático y CDN global
Preguntas frecuentes
¿Qué diferencia hay entre un error 502 y un 504?
Un 502 significa que el proxy recibió una respuesta inválida (o ninguna, porque la conexión fue rechazada o se cortó). Un 504 significa que el proxy se conectó pero la app no respondió a tiempo.
¿Un error 5xx es culpa mía o del visitante?
La clase 5xx significa que el servidor no pudo atender una petición válida, así que la causa está del lado del servidor. Recargar, borrar las cookies o cambiar de navegador rara vez ayuda.
¿Un error 503 perjudica el SEO?
Una caída corta suele hacer poco daño: Google reduce el rastreo cuando ve errores 5xx y mantiene las URLs ya indexadas durante un tiempo. Las URLs que siguen devolviendo un error de servidor acaban saliendo del índice.
¿Por qué recibo un 502 justo después del deploy?
Normalmente la app falló al arrancar, todavía está iniciando o escucha en un puerto o una dirección distintos de los que espera el proxy. Los logs de la app muestran cuál de ellos es.
Más en Sitios web
Ver los 20 artículos- Qué es un sitio estático y cómo hospedarloUn sitio estático es un conjunto de archivos HTML, CSS y JavaScript ya listos, entregados igual a todos los visitantes. Mira cómo funciona y dónde hospedarlo.
- ¿Cuánto cuesta hospedar una página web?Hospedar una página web cuesta desde cero hasta unas decenas de dólares al mes. Mira qué entra en la cuenta: hosting, dominio, tráfico y extras, con límites reales.
- ¿Cuánto cuesta hospedar un sitio estático?Hospedar un sitio estático cuesta entre cero y unas decenas de dólares al mes en la mayoría de los casos. Mira cómo el tráfico define el precio, paso a paso.
- ¿Cuánto cuesta hospedar una aplicación Next.js?Hospedar una app Next.js cuesta desde cero, con export estático, hasta decenas de dólares al mes con servidor. Modelos de cobro, cuentas de tráfico y costos ocultos.