|

Por qué tu Cloudflare Worker redirect nunca se ejecuta

En pocas palabras: Tu Worker no redirige porque, con Workers Static Assets activado, Cloudflare sirve cualquier request que matchea un archivo directo desde el edge sin invocar tu código. El fetch handler solo corre para rutas sin archivo. Solución: activá run_worker_first en tu wrangler.toml para interceptar todo el tráfico.

Escribiste un redirect de www al dominio apex dentro del fetch handler de tu Cloudflare Worker, lo deployaste, y quedó ahí, prolijo, visible en el dashboard. Y sin embargo tu Cloudflare Worker redirect no funciona: entrás a www.tusitio.com/about y te sirve la página igual, sin 301 ni 302. Le metés un console.log y no aparece nada en producción. El handler no está lento ni tira error: no se está ejecutando.

Un Cloudflare Worker es un script serverless que corre en el edge de Cloudflare para interceptar y modificar requests HTTP. Con la función de static assets activada, cualquier request que coincida con un archivo de tu carpeta de assets se sirve directo desde el edge y el Worker ni se invoca. El Worker es el fallback para las rutas que no resuelven a un archivo, no la puerta de entrada de todo el tráfico.

En 30 segundos

  • Con Workers static assets, los requests que matchean un archivo se sirven en el edge sin invocar tu Worker.
  • Tu fetch handler solo corre para rutas que NO resuelven a un archivo: 404s, paths inexistentes, rutas dinámicas.
  • Un redirect global (www a apex) en el Worker se ejecuta solo para las URLs que nadie visita, porque cada página real tiene un archivo detrás.
  • Test rápido: pedí /definitely-not-a-real-path. Si eso redirige y una página real no, confirmaste el problema.
  • La solución no es el Worker: usá Bulk Redirects o reglas de routing, que corren antes del asset check.

Cloudflare es un servicio de red de distribución de contenido (CDN) y proxy inverso fundado en 2010 que acelera sitios web, protege contra ataques DDoS y proporciona servicios de DNS y cortafuegos de aplicación.

¿Por qué el redirect está deployado pero nunca se ejecuta?

Porque el Worker ni siquiera se llama para esas URLs. El autor del post original en dev.to lo cuenta clarito: tenía el redirect de www a apex en el fetch handler, estaba deployado, y fue código muerto desde el minuto cero. No se dio cuenta durante semanas.

El detalle que engaña es que todo parece bien. Abrís el dashboard, leés la lógica del redirect, está ahí. El deploy dice success. Y el navegador te devuelve un 200 con tu página en vez del 301 que esperabas. No hay error que te avise. Ese es el peor tipo de bug: el que no rompe nada de forma visible.

¿Y por qué pasa esto justo con un redirect global? Porque un redirect de dominio aplica, en teoría, a TODAS las URLs. Pero las URLs reales de tu sitio tienen un archivo estático detrás (el HTML de /about, por ejemplo). Ese archivo se sirve en el edge y tu código nunca ve el request. Lo explicamos a fondo en nuestro artículo sobre secretos en Workers.

¿Cómo maneja Cloudflare los static assets frente al Worker?

cloudflare worker redirect diagrama explicativo

Cloudflare resuelve primero contra los static assets y solo si no hay match ejecuta tu Worker. Según la documentación oficial de Workers static assets, los requests que coinciden con un archivo de tu directorio de assets se sirven directo desde el edge, y el script del Worker no se invoca.

Es el comportamiento por defecto, y es el correcto. Fijate el motivo: así los assets estáticos son rápidos y no te facturan una invocación de Worker. Servir un CSS o una imagen no tiene por qué gastar tiempo de cómputo. Cloudflare lo entrega y listo.

El flujo de decisión es simple:

  • Hay match de archivo: Cloudflare sirve el asset en el edge. Tu Worker no corre.
  • No hay match: el request cae en el fetch handler de tu Worker, que actúa de fallback.

Como lo resume el autor en una sola frase: tu Worker es el fallback, no la puerta de entrada. Y esa distinción cambia todo el diseño.

¿Cuándo se ejecuta realmente tu Cloudflare Worker?

Tu Worker corre solo para los requests que no resuelven a un archivo estático. En la práctica: rutas inexistentes, 404s, paths que no mapean a ningún asset, y rutas dinámicas que definís vos. Para todo lo demás (HTML, CSS, JS, imágenes que estén en la carpeta de assets) Cloudflare sirve el archivo y saltea tu código.

En el caso del post, el redirect corrió para exactamente las URLs que nadie visita. Cada página real tenía un archivo detrás, o sea que el Worker se salteaba, o sea que el redirect no pasaba nunca. Los únicos requests que llegaban al código eran 404s. Cubrimos ese tema en detalle en tu infraestructura de DNS autoritativo.

Hay un test de 30 segundos para verificarlo. Pedí primero la home:

  • Request a una página real (por ejemplo www.tusitio.com/): si te devuelve un 200 con la página y ningún 301/302, el Worker no la tocó.
  • Request a algo que no existe (www.tusitio.com/definitely-not-a-real-path): si ESO redirige, confirmaste el diagnóstico. Tu código funciona, pero solo lo alcanzan los requests sin archivo detrás.

¿Cómo debuguear si tu Worker se ejecuta o no?

La forma más rápida es un console.log al inicio del fetch handler más los logs en tiempo real del dashboard de Cloudflare. Si pedís una página real y el log no aparece, el Worker no se está ejecutando para esa ruta. Punto. No es que falla: es que no lo llaman.

Tres cosas que conviene tener claras cuando debugueás esto:

  • Probá contra un path inexistente: si el log aparece con /no-existe-123 pero no con /about, ya sabés que el asset se sirve primero.
  • Mirá los logs en producción, no en local: en desarrollo el comportamiento es distinto y te puede dar un falso positivo (ya vamos a eso).
  • Usá la pestaña Network de DevTools: revisá el status code real y los headers de respuesta. Un 200 donde esperabas un 301 es la pista.

Ojo con una trampa mental: ver el código en el dashboard no prueba que se ejecute. Deployado no es lo mismo que invocado.

¿Cómo configurar un redirect que sí funcione con static assets?

Sacá el redirect global del Worker y ponelo en una capa que corra antes del asset check. Para un redirect de dominio como www a apex, la herramienta indicada son los Bulk Redirects de Cloudflare o las reglas de routing, no el fetch handler. Esas reglas se evalúan antes de que Cloudflare decida servir el archivo estático, así que aplican a todas las URLs, incluidas las que tienen un asset detrás.

Opciones concretas, de mayor a menor comodidad:

  • Bulk Redirects: ideal para redirects estáticos y masivos (dominio a dominio, cambios de URL). No gastan invocación de Worker y corren en la capa de routing.
  • Reglas de routing / Redirect Rules: para condiciones por hostname o path, configuradas en el panel sin escribir código.
  • Worker con guardas explícitas: si igual necesitás lógica dinámica, escribí el redirect asumiendo que solo te llegan las rutas sin archivo, y no lo uses para el redirect global.

La pregunta que conviene hacerse antes de tocar código: ¿este redirect necesita lógica de verdad, o es una regla fija que puede vivir en la configuración del hosting o del CDN? Si es fija, no la metas en un Worker. Para más detalles técnicos, mirá si usas Cloudflare Containers en producción.

¿Para qué sí sirve un Cloudflare Worker entonces?

Los Workers son potentes para lógica dinámica, no para interceptar assets estáticos. Según la documentación de Cloudflare Workers, corren código serverless en el edge, y ahí es donde brillan: en todo lo que NO es un archivo servido tal cual.

Casos reales donde el Worker sí se ejecuta y aporta:

  • Rutas API dinámicas: endpoints que generan respuesta al vuelo, sin archivo detrás.
  • Páginas 404 custom: justo el request que cae en el fallback, tu terreno.
  • Modificación de headers y validación: chequear tokens, agregar headers de seguridad, filtrar bots.
  • Contenido on-the-fly: personalización, A/B testing, rewriting condicional de rutas no mapeadas.

El punto es separar “falla” de “mal uso”. Poner un redirect global en el Worker no es un bug de Cloudflare: es usar la herramienta para algo que no le toca. Si sos de los que tercerizan el hosting y el DNS en un proveedor local como donweb.com y solo usás Cloudflare como CDN, esta distinción te ahorra horas de debug ciego.

¿Cuál es la diferencia entre desarrollo y producción en Cloudflare?

En local, sin static assets configurados, el Worker intercepta TODO; en producción, con los assets activos, el Worker pasa a ser fallback. Por eso un redirect que anda perfecto en desarrollo se muere en prod: cambian las reglas del juego entre un entorno y el otro, y nadie te avisa.

Pensalo así: probás el redirect en local, funciona bárbaro, lo deployás confiado, y de repente en producción cada página real sirve el archivo estático, el Worker se saltea, el redirect no dispara y vos jurás que el código está bien porque lo viste andar hace cinco minutos. El código estaba bien. El entorno no era el mismo.

La forma de evitarlo es testear en un staging que replique la configuración de assets de producción. No confíes en el comportamiento de dev para un redirect global.

Para profundizar en esto, tenemos un artículo sobre Cloudflare Worker routing.

Errores comunes al configurar redirects en Cloudflare

  • Asumir que “deployado” es “ejecutado”: ver el código en el dashboard no prueba nada. Verificá con un console.log y un request a una ruta sin archivo detrás.
  • Testear solo en desarrollo: en dev el Worker intercepta todo y te da un falso positivo. Confirmá siempre en producción o en un staging con static assets activados.
  • Meter un redirect global en el fetch handler: corre solo para las URLs sin archivo, o sea casi ninguna. Usá Bulk Redirects o reglas de routing.
  • Debuggear solo la home: si probás únicamente una página real te confundís. Compará una ruta con archivo contra una inexistente para ver la diferencia.

Preguntas Frecuentes

¿Por qué mi Cloudflare Worker no se ejecuta en producción?

Porque tenés static assets configurados y el request coincide con un archivo. Cloudflare sirve ese archivo directo en el edge y no invoca tu Worker. El fetch handler solo corre para rutas que no resuelven a un archivo, como 404s o paths dinámicos. Relacionado: cuando albergas assets estáticos en R2.

¿Cómo hago un redirect de www a apex en Cloudflare?

Usá Bulk Redirects o una Redirect Rule en el panel, no un Worker. Esas reglas se evalúan antes del chequeo de static assets, así que aplican a todas las URLs, incluidas las que tienen un archivo detrás. Un redirect global en el fetch handler solo alcanzaría las rutas inexistentes.

¿Por qué mi console.log del Worker no aparece?

Porque el Worker no se está ejecutando para ese request. Si pedís una página con un archivo estático detrás, Cloudflare la sirve en el edge sin llamar tu código, así que el log nunca dispara. Probá con un path inexistente y vas a ver el log aparecer.

¿Cómo sé si un request está pasando por mi Worker?

Hacé un request a una URL que no exista, como /definitely-not-a-real-path. Si esa ruta ejecuta tu lógica pero una página real no, confirmaste que el Worker corre solo como fallback. Los logs en tiempo real del dashboard te lo muestran al instante.

¿Es un bug de Cloudflare que el Worker no corra?

No, es el comportamiento por defecto y buscado. Servir static assets sin invocar el Worker hace que los archivos sean rápidos y no te facturen una invocación. El “error” está en esperar que el Worker intercepte tráfico que Cloudflare resuelve antes con un archivo.

Conclusión

Lo que cambió acá no es Cloudflare: es entender el orden de ejecución. Con static assets activados, el archivo se sirve primero y tu Worker es el fallback, no la puerta de entrada. Un redirect global metido en el fetch handler queda como código muerto para todas las páginas que tienen un archivo detrás, que en la práctica son casi todas.

Qué hacer, concreto: sacá los redirects fijos del Worker y llevalos a Bulk Redirects o Redirect Rules, que corren antes del asset check. Reservá el Worker para lógica dinámica de verdad (APIs, 404 custom, headers). Y antes de dar algo por funcionando, corré el test de los dos requests: una página real contra un path inexistente. Si solo redirige el que no existe, ya sabés dónde mirar.

Fuentes

Te puede interesar...