# Solución de problemas de la caché

> Averigua por qué no se cachea una respuesta, por qué los visitantes siguen viendo contenido antiguo tras un cambio y por qué no aparecen las Early Hints.

Empieza por las cabeceras de respuesta de la URL:

```sh
curl -sI https://www.example.com/ruta | grep -i -E 'x-cache-status|cache-status|age|cache-control|set-cookie|vary'
```

`Cache-Status` explica el motivo en `detail`; todos los valores están en [Cabeceras de estado de la caché](https://developers.openwaf.dev/es/cache/cache-status/#cache-status).

## No hay cabecera X-Cache-Status

La caché no intervino: la respuesta vino del propio borde (un bloqueo del WAF, un reto, la puerta de acceso o una redirección) o el nombre no pasa por el proxy de OpenWAF. Comprueba que la petición llega al borde y, tras un cambio de ajustes, que la versión nueva se ha propagado (**Cambios › Propagación**).

## Siempre DYNAMIC

| `detail` | Solución |
|---|---|
| `extension` | El tipo de fichero no está en la [lista por defecto](https://developers.openwaf.dev/es/cache/default-behavior/#default-extensions). Añade una [regla](https://developers.openwaf.dev/es/cache/cache-rules/) `cache` para él (HTML, JSON…). |
| `rule` | Casa una regla `bypass`. Recuerda que gana la última regla que casa. |
| `dev-mode` | El [modo desarrollo](https://developers.openwaf.dev/es/cache/configure/#development-mode) está activado en la zona o en el nombre. |
| `disabled` | La caché está desactivada para este nombre: revisa **Ámbito**, un nombre puede tener su propio valor. |
| `query` | El nivel de caché es *Sin cadena de consulta* y la URL lleva consulta. |
| `vary` | La petición trae una cabecera listada en el `vary_bypass_if_present` de una regla. |
| `method`, `upgrade`, `body` | Solo se cachean `GET` y `HEAD` sin cuerpo. |
| `path` | La ruta contiene `;`, un `/` o `\` codificado, o un segmento que acaba en punto. |

## Siempre MISS o BYPASS

| `detail` | Solución |
|---|---|
| `set-cookie` | El origen pone una cookie en esta respuesta. Deja de ponerla en los recursos públicos, envía `Cache-Control: private="Set-Cookie"` o usa una regla con `edge_ttl.mode` `override` si la página es igual para todos. |
| `private`, `no-store` | La `Cache-Control` del origen prohíbe las cachés compartidas. Envía `public, max-age=…`, o dirígete solo al borde con `OpenWAF-CDN-Cache-Control`. |
| `uncacheable` | No hay `Cache-Control`, `Expires` ni TTL por defecto aplicable; es lo típico del HTML que una regla hace elegible. Haz que el origen envíe frescura o fija un TTL del borde en la regla. |
| `vary` | El origen envía `Vary` con una cabecera distinta de `Accept-Encoding`, `Accept` (imágenes) u `Origin`. Quítala o lístala en el `vary_bypass_if_present` de una regla. |
| `auth` | La petición traía `Authorization`; la respuesta debe decir `public`, `s-maxage` o `must-revalidate` para compartirse. |
| `size` | Mayor que `cache.max_object_mb`. Súbelo (hasta 512). |
| `deception` | El tipo de contenido no encaja con la extensión. Corrige el `Content-Type` del origen. |
| `personal` | Un documento (`pdf`, `docx`…) pedido con cookies, sin frescura explícita del origen. |
| `status` | El código de estado no se puede guardar. |

Un `MISS` en la segunda petición también puede significar que llegó a otro nodo del borde: cada nodo tiene su propia caché.

## Los visitantes siguen viendo contenido antiguo

- [Purga](https://developers.openwaf.dev/es/cache/purge/) las URL, un prefijo, el nombre o una etiqueta. Comprueba en **Purgas recientes** que se aplicó en todos los nodos.
- En una purga por URL, la cadena de consulta cuenta: `app.css?v=2` y `app.css` son URL distintas.
- Los navegadores pueden guardar su propia copia durante el `max-age` que recibieron. Una purga no vacía la caché del navegador; usa nombres de recurso versionados o valores de `max-age` más cortos.
- Tras desplegar un sitio con recursos con hash, purga el HTML: las páginas antiguas apuntan a los ficheros del build anterior.

## La purga responde 429

La organización alcanzó los [límites de purga](https://developers.openwaf.dev/es/cache/purge/#limits). Espera los segundos de `Retry-After` o agrupa valores: una purga admite hasta 100, y un prefijo o una etiqueta suelen sustituir a muchas URL.

## No llegan las 103 Early Hints

- La página salió de la caché (`HIT`): las pistas solo se envían cuando la petición espera al origen.
- El nodo aún no ha visto un `200` HTML compartible de la página; vuelve a pedirla.
- La petición no es una navegación: necesita `Accept: text/html`, `GET`, sin `Range`, por HTTP/1.1 o HTTP/2.
- Los enlaces apuntan a un origen que no está en `early_hints.extra_origins`, o no son `https`.

Consulta [Early Hints](https://developers.openwaf.dev/es/cache/early-hints/).
