304 Not Modified: qué es y cómo funciona

Qué significa HTTP 304 Not Modified, por qué pertenece a la clase 3xx pero no es una redirección, cómo funcionan ETag y Last-Modified y cómo puede mejorar indirectamente la eficiencia del rastreo sin cambiar el posicionamiento.

Publicado por primera vez: 3 jul 2026 · Última actualización: 8 ago 2026 · Avanzado
Idiomas
1 señal de evidencia en esta página

HTTP 304 Not Modified es la respuesta a una solicitud GET o HEAD condicional cuya condición resulta falsa y que, de otro modo, habría recibido un 200. Es una respuesta de la clase 3xx, pero no es una redirección: no tiene cabecera Location ni cuerpo. Cuando el validador If-None-Match/ETag o If-Modified-Since/Last-Modified sigue coincidiendo, el servidor devuelve 304 y el cliente reutiliza su copia en caché. No tiene efecto directo en el posicionamiento; Google ya tiene el contenido, aunque Search aún puede recalcular las señales de una URL. En sitios grandes con muchas URL que cambian rara vez, una 304 ahorra ancho de banda y cálculo y puede mejorar indirectamente la eficiencia del rastreo. Google recomienda ETag como validador principal y admite configurar ambos. No la confundas con 301/302/307/308, que mueven a otra URL, ni con 204 No Content, que tampoco tiene cuerpo pero por una razón distinta.

TL;DR — Una 304 es la respuesta a una solicitud condicional GET/HEAD cuya condición resulta falsa y que, de otro modo, habría recibido un 200 (RFC 9110 §15.4.5). Pertenece a la clase 3xx, pero no es una redirección: no hay Location, URL nueva ni —normativamente— cuerpo (“it cannot contain content or trailers”). La condición se transporta mediante If-None-Match (frente a un ETag) o If-Modified-Since (frente a Last-Modified); si el validador sigue coincidiendo, el servidor devuelve 304 y el cliente reutiliza su caché. Impacto SEO: ningún efecto directo en el posicionamiento —Google ya tiene el contenido, aunque Search aún puede recalcular señales— y ahorro de recursos en sitios grandes (Google dice que puede mejorar indirectamente la eficiencia del rastreo; no promete reasignar automáticamente el presupuesto de rastreo a otras URL). La infraestructura de rastreo de Google admite ambos validadores y recomienda ETag como principal porque no tiene problemas de formato de fecha. Compárala con 301/302/307/308 (que trasladan la URL) y 204 (también sin cuerpo, pero porque realmente no hay nada que enviar).

Qué significa 304 en la especificación

RFC 9110 (HTTP Semantics) §15.4.5 lo define con precisión: “The 304 (Not Modified) status code indicates that a conditional GET or HEAD request has been received and would have resulted in a 200 (OK) response if it were not for the fact that the condition evaluated to false.” (traducción) «El código de estado 304 (Not Modified) indica que se recibió una solicitud GET o HEAD condicional que habría producido una respuesta 200 (OK) si no fuera porque la condición se evaluó como falsa». Ese es el disparador normativo: una solicitud condicional GET/HEAD cuya condición resulta falsa y que, de otro modo, habría recibido un 200. En términos sencillos: el cliente preguntó “dame esta página, pero solo si cambió”, el servidor determinó que no cambió y omite el cuerpo. “Segunda visita” es el ejemplo cotidiano de cómo una solicitud se vuelve condicional (el cliente adjunta un validador guardado de una respuesta anterior), pero es un ejemplo didáctico, no la regla: la especificación no exige una visita previa, solo una solicitud condicional. Evidence for this claim RFC 9110 defines 304 Not Modified as the response to a conditional GET or HEAD when the selected representation has not changed and says the response cannot contain content. Scope: HTTP semantics for 304 conditional responses. Confidence: high · Verified: IETF: RFC 9110 §15.4.5 — 304 Not Modified

La especificación incluso usa la palabra “redirecting” en esta sección: “the server is therefore redirecting the client to make use of that stored representation as if it were the content of a 200 (OK) response” (traducción) «por tanto, el servidor redirige al cliente para que use esa representación almacenada como si fuera el contenido de una respuesta 200 (OK)». Pero léelo con cuidado: redirige al cliente a su propia caché, no a otra URL. No hay cabecera Location ni dirección nueva. Esta frase es el origen de gran parte de la confusión sobre si una 304 “es una redirección”. No lo es en el sentido HTTP.

Hay otros dos puntos normativos importantes:

  • Nunca hay cuerpo. RFC 9110 dice: “A 304 response is terminated by the end of the header section; it cannot contain content or trailers.” (traducción) «Una respuesta 304 termina al final de la sección de cabeceras; no puede contener contenido ni tráileres». Una 304 que envía cuerpo viola la especificación y algunos clientes la gestionarán mal. Es una regla estricta, no una preferencia de estilo.
  • Transporta los mismos metadatos que enviaría un 200. El servidor “MUST generate any of the following header fields that would have been sent in a 200 (OK) response to the same request: Content-Location, Date, ETag, and Vary” (traducción) «DEBE generar cualquiera de los siguientes campos de cabecera que se habría enviado en una respuesta 200 (OK) a la misma solicitud: Content-Location, Date, ETag y Vary», además de Cache-Control y Expires cuando corresponda. Una 304 son las cabeceras del 200 sin la carga útil.
Evidence for this claim A 304 response terminates after the header section and cannot contain content or trailers. Scope: conditional GET and HEAD Confidence: high · Verified: RFC 9110 §15.4.5: 304 Not Modified

Cómo funciona realmente una 304: solicitudes condicionales

Un servidor nunca envía una 304 de la nada. Siempre responde a una solicitud condicional: una solicitud que el cliente hace condicional al adjuntar un validador guardado de una respuesta anterior. Hay dos validadores.

ETag e If-None-Match

Un ETag (etiqueta de entidad) es un token opaco que el servidor adjunta a una respuesta 200; imagínalo como la huella de versión de esa representación exacta de la URL. En la siguiente solicitud a esa URL, el cliente devuelve el valor guardado en una cabecera If-None-Match. El servidor compara: si el ETag actual sigue coincidiendo, nada cambió y devuelve 304; si difiere, devuelve un 200 nuevo con el contenido actualizado y un ETag nuevo.

Last-Modified e If-Modified-Since

La alternativa basada en fecha: el servidor envía una marca de tiempo Last-Modified en el 200. La próxima vez, el cliente la devuelve en una cabecera If-Modified-Since y el servidor compara las fechas: si el recurso no ha cambiado desde esa marca, es un 304. Es más sencilla pero más tosca (solo tiene la granularidad de la marca de tiempo) y sensible al formato exacto de la fecha HTTP, una fuente habitual de errores. Cuando están presentes ambos validadores, If-None-Match (el ETag) tiene prioridad sobre If-Modified-Since.

ETag fuertes y débiles

Un ETag puede ser fuerte o débil, y la diferencia importa. Según la guía de solicitudes condicionales de MDN, “strong validation consists of guaranteeing that the resource is, byte to byte, identical to the one it is compared to.” (traducción) «la validación fuerte consiste en garantizar que el recurso es idéntico, byte a byte, al recurso con el que se compara». Un ETag débil lleva el prefijo W/ (por ejemplo, ETag: W/"abc123") y solo afirma equivalencia semántica: el ejemplo de MDN es que “a page that would differ from another only by a different date in its footer, or different advertising, would be considered identical to the other with weak validation.” (traducción) «una página que solo se diferenciara de otra por una fecha distinta en el pie o por publicidad distinta se consideraría idéntica mediante validación débil». Los ETag fuertes (sin prefijo) son necesarios para cosas como solicitudes de rango que exigen coincidencia exacta de bytes; los débiles sirven cuando la compresión, los espacios o diferencias triviales sin importancia sustantiva no deberían forzar una descarga completa. La trampa práctica: si el ETag cambia cada vez que el contenido se vuelve a comprimir con gzip/Brotli o varía entre servidores con balanceo de carga, provocarás nuevos rastreos innecesarios. Elige fuerte o débil deliberadamente y mantén estable el valor cuando el contenido no haya cambiado realmente.

El intercambio completo, paso a paso

  1. Primera solicitud → el servidor devuelve 200 OK con el contenido y ETag o Last-Modified.
  2. El cliente guarda el contenido y esos validadores.
  3. Siguiente solicitud → el cliente envía If-None-Match o If-Modified-Since con los valores guardados.
  4. El servidor decide: sin cambios → 304 Not Modified, sin cuerpo, y el cliente reutiliza su caché; con cambios → 200 OK con el cuerpo nuevo y validadores actualizados. Evidence for this claim RFC 9111 defines validation as checking whether a stored response remains current, typically with a conditional request that can receive 304 Not Modified. Scope: HTTP cache validation; it does not create a Search ranking benefit. Confidence: high · Verified: IETF: RFC 9111 §4.3 — Validation

Si quieres un tratamiento más profundo de la caché y los validadores como palanca de eficiencia de rastreo —la historia completa de las solicitudes condicionales y su relación con el presupuesto de rastreo—, es un tema complementario; este artículo se centra en el código de estado.

304 y SEO: ningún efecto en el posicionamiento, sí en la eficiencia del rastreo

Esta es toda la historia SEO y es más estrecha de lo que sugiere mucho texto genérico de blogs. 304 no tiene efecto directo en el posicionamiento, y la propia orientación de Google sobre cómo los códigos de estado afectan al rastreo y la indexación limita también el efecto de indexación: Search aún puede recalcular las señales de una URL, pero una 304 no cambia de otro modo cómo se indexa la página. Google ya tiene el contenido del rastreo anterior; una 304 solo confirma que no cambió y conserva lo que tiene. No hay una bonificación de posicionamiento por devolver 304.

Lo que sí te aporta una 304 es ahorro de recursos que puede mejorar indirectamente la eficiencia del rastreo. En la publicación de Google Search Central de diciembre de 2024 sobre caché HTTP, Gary Illyes explicó que la caché local puede hacer más eficiente el rastreo de sitios grandes con contenido que cambia poco y que Google admite ETag, If-None-Match, Last-Modified e If-Modified-Since.

Sobre el mecanismo exacto de la 304, la misma publicación explica por qué el cuerpo vacío es el punto central: si el ETag que envía el rastreador “matches the current value the server generated, your server should return an HTTP 304 (Not modified) status code with no HTTP body” (traducción) «coincide con el valor actual generado por el servidor, tu servidor debe devolver un código de estado HTTP 304 (Not modified) sin cuerpo HTTP», y esa parte de “no HTTP body” (traducción) «sin cuerpo HTTP» importa porque “your server doesn’t have to spend compute resources on actually generating content” (traducción) «tu servidor no tiene que gastar recursos de cálculo en generar contenido» y “doesn’t have to transfer the HTTP body” (traducción) «no tiene que transferir el cuerpo HTTP»; ahorras cálculo y ancho de banda en ambos extremos. El lenguaje de Google sobre el beneficio posterior es condicional: esos ahorros pueden mejorar indirectamente la eficiencia del rastreo. No promete que el esfuerzo ahorrado se reasigne automáticamente a tus URL nuevas o actualizadas; trátalo como un mecanismo de ahorro con un beneficio plausible, no garantizado.

Por qué importa más en sitios grandes

Si tienes unos cientos de páginas, esto es bastante académico: Google rastreará cómodamente todo tu sitio. El beneficio escala con el tamaño: un sitio con cientos de miles o millones de URL, muchas de ellas con cambios poco frecuentes, gana de forma tangible cuando los rastreadores pueden evitar volver a obtener todas las que no cambiaron. Ese es el público al que se dirige la publicación de Google y ese es el encuadre honesto: no vendas la 304 como una táctica para sitios pequeños.

ETag o Last-Modified, y qué cuenta como “cambio”

Google recomienda ETag como validador principal: “We strongly recommend using ETag because it’s less prone to errors and mistakes (the value is not structured unlike the Last-Modified value).” (traducción) «Recomendamos encarecidamente usar ETag porque es menos propenso a errores y equivocaciones (el valor no tiene estructura, a diferencia del valor Last-Modified)». Configurar ambos está bien y se recomienda. Si usas Last-Modified, la fecha “must be formatted according to the HTTP standard” (traducción) «debe tener el formato del estándar HTTP»; Google recomienda “Weekday, DD Mon YYYY HH:MM:SS Timezone,” (traducción) «Día de la semana, DD Mon AAAA HH:MM:SS Zona horaria,»; por ejemplo “Fri, 4 Sep 1998 19:15:56 GMT”, o puede ignorarse silenciosamente. Google también sugiere establecer el campo max-age de Cache-Control para ayudar a los rastreadores a decidir cuándo volver a rastrear.

Evidence for this claim Google's crawler guidance recommends ETag because its opaque value avoids date-formatting errors, while also allowing both ETag and Last-Modified; this is Google-specific operational advice, not a change to HTTP validator semantics. Scope: HTTP cache validation Confidence: high · Verified: Crawling December: HTTP caching

La decisión sobre qué cuenta como un cambio que merece invalidar la caché es tuya, y el consejo de Google es reservarlo para cambios sustantivos: “Our recommendation is that you require a cache refresh on significant changes to your content; if you only updated the copyright date at the bottom of your page, that’s probably not significant.” (traducción) «Nuestra recomendación es que exijas una actualización de la caché cuando haya cambios significativos en el contenido; si solo actualizaste la fecha de copyright al pie de la página, probablemente no sea significativo».

Qué hacen realmente Googlebot y Bingbot

No todas las solicitudes de rastreadores son condicionales. La documentación de rastreo de Google señala que cada rastreador y recuperador de Google varía en cuanto al soporte de caché según el producto al que sirve: Googlebot admite caché al volver a rastrear URL para Search, mientras que algunos recuperadores de Google solo la admiten en determinadas condiciones. Por tanto, aunque las cabeceras estén bien configuradas, no esperes que el 100 % de las solicitudes lleve If-None-Match/If-Modified-Since. En Bing, las solicitudes condicionales no son una función exclusiva de Google. El rastreador de Bing admite solicitudes GET condicionales (envía If-Modified-Since y, cuando está disponible, If-None-Match, y acepta una 304 cuando el contenido no cambió) desde al menos una publicación de Live Search de 2008, aunque Bing no ha publicado un equivalente moderno del texto de Google de 2024. Trátalo como comportamiento HTTP genérico aplicable a ambos motores.

Cómo implementar el soporte de 304

  1. Envía validadores en el 200. Configura tu servidor, CDN o aplicación para adjuntar un ETag (recomendado) o una cabecera Last-Modified correctamente formateada a las respuestas 200 normales. Muchos servidores y frameworks generan ETag automáticamente para archivos estáticos; las respuestas dinámicas suelen requerir que lo actives.
  2. Respeta las cabeceras condicionales al recibirlas. Cuando llegue una solicitud con If-None-Match/If-Modified-Since, compárala con el validador actual y devuelve 304 (sin cuerpo) si sigue coincidiendo, o un 200 nuevo si no coincide. De nuevo, los servidores de archivos estáticos suelen encargarse; las rutas de aplicación y los workers del edge a menudo no lo hacen si no los configuras.
  3. Decide qué significa “cambiado” y mantén estable el ETag para el contenido que no ha cambiado realmente; no dejes que una recompresión o la variación entre servidores lo cambie sin motivo.
  4. Vigila las configuraciones erróneas clásicas:
    • Siempre-200 — nunca se envían validadores, así que ninguna solicitud es condicional y nunca obtienes el beneficio de eficiencia.
    • ETag inestables — un valor que cambia aunque el contenido no cambie (balanceadores, recompresión), lo que fuerza descargas constantes.
    • 304 obsoletas — la peligrosa: un servidor sigue devolviendo 304 (o un ETag sin cambios) después de que el contenido haya cambiado, de modo que rastreadores y cachés nunca reciben la actualización. Es un error que debes detectar en el análisis de logs, no un defecto inherente de la 304.

304 frente a otros códigos de estado

304 frente a 301 / 302 / 307 / 308

Esos sí son redireccionamientos reales. Un 301/308 (permanente) o 302/307 (temporal) lleva una cabecera Location y mueve al cliente a una URL diferente; además, 301/308 transmiten una señal de canonicalización. Una 304 no tiene Location, no mueve a nadie y no transmite una señal de posicionamiento. Pertenecen a la misma familia 3xx por número, pero cumplen trabajos completamente distintos. Los detalles de cada código de redirección están en sus propios artículos (consulta el artículo sobre la redirección 301 y el subcentro de redirecciones).

304 frente a 204 No Content

Ambas respuestas no tienen cuerpo, pero por razones completamente distintas. Una 204 No Content es un éxito 2xx con el cuerpo intencionadamente vacío porque el servidor no tiene nada que enviar realmente —por ejemplo, un DELETE/PUT de API correcto o una baliza de analítica—. Una 304 tampoco envía cuerpo, pero no porque no haya nada que enviar: significa “ya lo tienes y sigue siendo válido”. No las confundas: una 204 en una URL de página puede tratarse como un soft 404 porque no hay contenido indexable, mientras que una 304 confirma la validez del contenido que Google ya tiene. El artículo sobre 204 No Content cubre ese código por completo.

Mitos habituales sobre 304

  1. “304 es una redirección”. No tiene cabecera Location y nadie va a ningún sitio. El cliente reutiliza su propia copia en caché. El “redirecting the client to make use of that stored representation” (traducción) «redirigir el cliente para que utilice esa representación almacenada» de RFC 9110 significa volver a la caché, no ir a otra URL.
  2. “304 es un error que debo solucionar”. Es el resultado correcto y esperado de una configuración funcional de solicitudes condicionales. Ver 304 en un rastreo o en DevTools indica que la caché funciona: es la confusión más habitual en las SERP.
  3. “304 ayuda al posicionamiento”. No existe un efecto directo de posicionamiento y Google también limita el efecto de indexación: Search puede recalcular las señales de una URL, pero una 304 no cambia de otro modo la indexación. El beneficio es el ahorro de recursos que Google dice que puede mejorar indirectamente la eficiencia del rastreo en sitios muy grandes; no es una señal de posicionamiento ni una garantía de que el esfuerzo ahorrado pase a otras URL.
  4. “If my server returns 304, Google will use stale content forever.” (traducción) «Si mi servidor devuelve 304, Google usará contenido obsoleto para siempre». La 304 solo se activa mientras el validador coincide. En cuanto cambia el contenido de verdad, un servidor bien implementado devuelve un 200 nuevo con validadores nuevos. El riesgo real es un servidor mal configurado que continúa devolviendo 304 después de un cambio: es un error, no una propiedad de la 304.
Evidence for this claim RFC 9111 defines validation as checking whether a stored response remains current, typically with a conditional request that can receive 304 Not Modified. Scope: HTTP cache validation; it does not create a Search ranking benefit. Confidence: high · Verified: IETF: RFC 9111 §4.3 — Validation
  1. “ETag y Last-Modified son intercambiables”. Ambos son validadores, pero Last-Modified depende del formato de fecha y solo tiene la granularidad de su marca de tiempo, mientras que ETag es opaco y preciso (aunque puede variar de forma problemática entre servidores o después de una recompresión si se implementa mal). Google recomienda ETag como principal y usar ambos si puedes.

Preguntas frecuentes

¿HTTP 304 es un error? No: es una señal de éxito que indica que la caché funciona. Significa que la copia guardada por el cliente sigue siendo válida.

¿304 Not Modified es una redirección? No. Pertenece a la clase 3xx por numeración, pero no tiene cabecera Location ni mueve al cliente a una URL nueva.

¿304 ayuda al SEO o al posicionamiento? No tiene efecto directo en el posicionamiento ni efecto de indexación más allá de que Google pueda recalcular las señales de una URL. Ahorra ancho de banda y cálculo al permitir que los rastreadores omitan páginas sin cambios, algo que Google dice que puede mejorar indirectamente la eficiencia del rastreo en sitios grandes.

¿Cuál es la diferencia entre ETag y Last-Modified? ETag es una huella opaca de versión que se compara mediante If-None-Match; Last-Modified es una marca de tiempo que se compara mediante If-Modified-Since. Google recomienda ETag porque es menos propenso a errores.

¿Qué es un ETag débil frente a uno fuerte? Un ETag fuerte afirma que el contenido es idéntico byte a byte; un ETag débil (con prefijo W/) afirma equivalencia semántica y tolera diferencias triviales, como la compresión o una fecha de pie de página modificada.

¿Por qué veo 304 en mis logs o informes de rastreo? Porque los clientes están haciendo solicitudes condicionales y tu servidor confirma correctamente que el contenido no cambió. Es algo esperado y positivo.

¿Cómo hago que mi servidor devuelva 304 correctamente? Envía ETag/Last-Modified en el 200 y, en la siguiente solicitud, respeta If-None-Match/If-Modified-Since devolviendo 304 sin cuerpo cuando el validador siga coincidiendo.

¿Cuál es la diferencia entre 304 y 204? Ambas respuestas no tienen cuerpo: 204 porque no hay nada que enviar y 304 porque ya tienes una copia que sigue siendo válida.

¿Googlebot envía cabeceras condicionales en todas las solicitudes? No. El soporte de caché varía según el rastreador, así que no todas las solicitudes serán condicionales aunque hayas configurado las cabeceras.

¿Puede una respuesta 304 tener cuerpo? No. RFC 9110 dice que “it cannot contain content or trailers” (traducción) «no puede contener contenido ni tráileres». Una 304 con cuerpo viola la especificación.

Evidence for this claim A 304 response terminates after the header section and cannot contain content or trailers. Scope: conditional GET and HEAD Confidence: high · Verified: RFC 9110 §15.4.5: 304 Not Modified

Try it live

This is a real endpoint on this site — not a simulation. Hit it from the button, open it in a new tab, or curl -i it from your terminal, and the server answers with the actual status code this article is about.

Open in new tab ↗

Add an expert note

Pin an expert quote

New person? Create their unclaimed profile at /admin/experts/ → Pin a quote first.