304 Not Modified: por qué es un éxito, no un error
304 Not Modified es un éxito: significa que tu copia en caché del recurso sigue vigente, así que el servidor no envía cuerpo y te dice que reutilices lo que ya tienes. Solo aparece como respuesta a una petición condicional, por lo que una comprobación de monitorización que no envía cabeceras de caché nunca verá una.
Cómo ocurre un 304
Un 304 es la segunda mitad de una conversación en dos pasos. En la primera petición el servidor devuelve el recurso con un validador: un ETag, que es un identificador opaco para esa versión exacta, y a menudo una fecha Last-Modified. El cliente guarda la respuesta junto con esos validadores.
Más tarde, cuando hay que revalidar la copia en caché, el cliente repite la petición e incluye lo que tiene:
If-None-Match: "abc123"lleva el ETag guardado. Es el validador preferido porque es exacto.If-Modified-Since: Wed, 03 Sep 2026 10:00:00 GMTlleva la fecha guardada, usada cuando no hay ETag.
Si el recurso no ha cambiado, el servidor responde 304 Not Modified solo con cabeceras y sin cuerpo, y el cliente renderiza su copia en caché. Si ha cambiado, el servidor responde 200 con el contenido nuevo y validadores nuevos. Ambos resultados son un comportamiento correcto.
Por qué un 304 son buenas noticias, no un error
La gente ve un 304 en el panel de red de un navegador o en un analizador de registros, nota que no es un 200 y asume que algo falló. No falló nada. Un 304 es la respuesta útil más barata de la web: ningún cuerpo de respuesta cruza la red, así que la transferencia son unos pocos cientos de bytes en lugar del recurso completo, y el servidor normalmente se ahorra tener que regenerar el recurso, así que cuesta menos CPU que un 200. La página se renderiza más rápido porque el navegador reutiliza bytes que ya tiene. Los rastreadores también se benefician, ya que un ETag estable que produce 304 deja que un buscador gaste su presupuesto de rastreo en páginas que sí cambiaron.
Una proporción alta de 304 en los recursos estáticos es señal de que la caché está bien configurada. Lo único que vigilar es si de verdad necesitas la ida y vuelta de revalidación: para recursos versionados o con huella digital, un Cache-Control: max-age largo con immutable evita incluso el 304, porque el navegador ni siquiera pregunta.
Cuándo un 304 es un problema
- Una página obsoleta que no se refresca. Si tu HTML se sirve con un validador que nunca cambia mientras el contenido sí lo hace, los navegadores siguen recibiendo 304 y los usuarios siguen viendo la página antigua. Es el clásico fallo de "lo desplegué pero nadie lo ve".
- Un 304 sin ninguna copia en caché que le corresponda. Si un cliente envía una petición condicional sin tener motivo para ello, o un proxy quita el cuerpo de un 200, el cliente se queda sin nada que renderizar y la página aparece en blanco.
- ETags débiles o inestables detrás de un balanceador de carga. Cuando varios backends generan ETags distintos para contenido idéntico, cada revalidación falla y obtienes 200 completos donde se esperaban 304. El tráfico sube sin motivo.
- La compresión cambiando el validador. Si el ETag difiere entre las variantes comprimida y sin comprimir sin un
Vary: Accept-Encodingcorrecto, las cachés pueden servir lo que no toca.
Cómo probar peticiones condicionales
- Obtén el recurso y lee sus validadores:
curl -sI https://example.com/style.css | grep -Ei "^(HTTP|etag|last-modified|cache-control)" - Repite la petición con el ETag que te dieron y confirma que el servidor responde 304:
Sustituye por el valor exacto del ETag, comillas incluidas. Un 200 aquí significa que la revalidación no está funcionando.curl -sI -H 'If-None-Match: "abc123"' https://example.com/style.css | head -n 1 - Si obtienes 200 cuando esperabas 304, comprueba si un proxy o una CDN está quitando
If-None-Match, y si tus backends coinciden en el ETag para el mismo archivo. - Si obtienes una página obsoleta, haz que el validador cambie cuando cambia el contenido. Los nombres de archivo con huella digital son la solución más fiable; si no, deriva el ETag del propio contenido.
- Mantén el HTML con un tiempo de frescura corto y deja que los recursos lleven el largo. Un HTML cacheado durante un día es lo que hace invisible un despliegue.
Por qué las comprobaciones de uptime nunca ven un 304
Una comprobación de uptime pide una página como si fuera un visitante por primera vez, sin If-None-Match ni If-Modified-Since, así que el servidor no tiene nada con qué comparar y siempre responde 200. Es el comportamiento por defecto correcto para la disponibilidad. También significa que las regresiones de caché no aparecen en absoluto en los datos de uptime: un sitio puede servirle a todo el mundo una página obsoleta mientras todas las comprobaciones siguen en verde. Haz aserciones sobre el contenido de la página además del estado, y una página que dejó de actualizarse se vuelve visible como un desajuste de contenido. HostTracker ofrece 13 tipos de monitor y monitoriza sitios web desde 2004. Prueba cabeceras y estado con la herramienta de comprobación HTTP, y consulta qué demuestra de verdad un 200 OK y la guía completa de la familia 3xx.