Cloudflare R2 con 404: el Worker wildcard que se lo comía
En pocas palabras: Si tu dominio personalizado de R2 tira 404 con el bucket y el DNS sanos, casi seguro un Worker con ruta wildcard (example.com/*) intercepta la solicitud: en el mismo hostname la ruta de Worker gana siempre. Solución: hacela más específica (example.com/api/*) o excluí el subdominio de media.
Si tu dominio personalizado de Cloudflare R2 devuelve 404 pero el bucket, los archivos y el DNS figuran como sanos, lo más probable es que un Worker con una ruta wildcard esté interceptando la solicitud antes de que R2 la vea. Las rutas de Workers tienen precedencia sobre los dominios personalizados de R2 en el mismo hostname. Ese es el Cloudflare R2 error 404 dominio personalizado que arruina tardes enteras.
En 30 segundos
- La causa real: un Worker con ruta
example.com/*captura tambiénmedia.example.com/archivo.mp4y responde antes que R2. - El síntoma que delata todo: el 404 tiene el estilo de tu propio sitio (tus fuentes, tu copy). Un bucket de .mp4 no debería servir HTML nunca.
- Quién gana: en el mismo hostname, la ruta de Worker tiene precedencia sobre el custom domain de R2. Siempre.
- La solución: hacé la ruta del Worker más específica (
example.com/api/*en vez deexample.com/*) o excluí el subdominio de media. - El caso documentado: 60 archivos de video en R2, todos con 404, un día entero perdido revisando lo que no estaba roto (según el caso documentado en dev.to).
Cloudflare es una plataforma de infraestructura en nube desarrollada por Cloudflare Inc. que proporciona CDN, DNS, protección DDoS y herramientas de seguridad para optimizar y proteger sitios web. Fue fundada en 2010.
Cloudflare R2 es el servicio de almacenamiento de objetos de Cloudflare, compatible con la API de S3 y sin cargos por egreso de datos. Un custom domain de R2 te deja servir esos objetos desde tu propio subdominio (por ejemplo, media.tudominio.com) en vez de la URL genérica del bucket. Cloudflare Workers, en cambio, son funciones serverless que corren en el edge y se activan según patrones de ruta. Cuando ambos comparten hostname, el Worker manda.
Este artículo salió de un caso real, así que vamos a los datos concretos.
¿Por qué mi dominio personalizado de R2 devuelve 404 si todo está sano?
Porque algo en tu cuenta responde la solicitud antes de que llegue a R2. En el caso documentado por Lucian Tudor en dev.to, había 60 archivos de video en un bucket servidos a través de media.example.com. Cada request devolvía 404. No un error de Cloudflare, no un XML de error del bucket. Un 404 pelado.
Fijate lo que estaba “sano” y no servía de nada revisar:
- Los archivos estaban en el bucket, con tamaños y content-types correctos.
- El custom domain figuraba como Active en la configuración de R2.
- El registro DNS estaba presente y proxeado (la nubecita naranja).
- Las claves de los objetos coincidían carácter por carácter con las rutas pedidas, mayúsculas incluidas.
- No había reglas de acceso a nivel bucket estorbando.
El autor resubió los archivos, recreó el custom domain, revisó las keys una por una. Todo desperdiciado, porque nada de eso estaba roto. ¿Y cuál fue la pista que lo cambió todo? La página 404 tenía su propio estilo. Sus fuentes. Su copy. Un bucket de videos no tiene por qué servir HTML, y mucho menos el HTML de tu sitio.
¿Cómo una ruta wildcard de Worker intercepta solicitudes a R2?
Una ruta wildcard como example.com/* coincide con cualquier path bajo ese patrón, y los Workers se evalúan antes que los custom domains de R2. Entonces media.example.com/clip-01.mp4 coincidió con el wildcard del Worker que servía el sitio principal, el Worker corrió su lógica, no encontró esa ruta en su router interno y devolvió su propia página 404. R2 nunca llegó a ver la solicitud. Te puede servir nuestra cobertura de gestionar secretos en tus Workers.
El orden mental es este: Cloudflare recibe el request, chequea si algún patrón de ruta de Worker aplica al hostname y path. Si aplica, ejecuta el Worker. Recién si ningún Worker coincide, la solicitud sigue el camino normal hacia el origen o hacia el custom domain de R2. El autor lo había configurado meses antes y dejó de pensar en eso. Clásico.
¿Qué tiene precedencia: un Worker wildcard o un R2 custom domain?
El Worker. En el mismo hostname, la ruta de Worker gana sobre el custom domain de R2 sin excepción. Esto está alineado con cómo Cloudflare documenta el enrutamiento: los patrones de ruta de Workers se resuelven en la capa de edge antes que otros servicios de la zona. Si asumís que R2 tiene prioridad porque “está configurado y activo”, vas a perder horas mirando el lado equivocado.
¿Cuál es la diferencia entre rutas wildcard y rutas específicas?
Una ruta wildcard usa el asterisco para capturar todo lo que cuelga de un patrón; una ruta específica limita el match a un path concreto. La diferencia parece obvia hasta que un * mal ubicado se traga subdominios enteros que ni sabías que estaban en juego.
Acá va la comparación que importa cuando mezclás Workers y R2 en la misma zona:
| Patrón de ruta del Worker | ¿Qué captura? | ¿Rompe tu R2 en media.example.com? |
|---|---|---|
example.com/* | Todo bajo el dominio raíz | No (solo el apex y sus paths) |
*.example.com/* | Todos los subdominios y sus paths | Sí, se come el subdominio de media |
*example.com/* | Apex y subdominios (match amplio) | Sí, muy probable |
example.com/api/* | Solo paths bajo /api | No, deja pasar media |
app.example.com/* | Solo el subdominio app | No, no toca media |

El punto es que un patrón que arranca con * o que incluye *.example.com abarca subdominios. Si tu R2 vive en un subdominio, ese wildcard lo va a interceptar. Tema relacionado: configurar DNS autoritativos correctamente.
¿Cómo diagnosticar si un Worker está bloqueando tu R2?
Mirá el contenido del 404, no el código. Si un subdominio que debería servir archivos binarios te devuelve la página de error de tu sitio (con tu diseño), algo más en tu cuenta está contestando antes que R2. Ese es el diagnóstico de una línea.
El paso a paso concreto:
- Abrí DevTools y mirá la respuesta: si el body del 404 es HTML con tu CSS, respondió un Worker, no R2. R2 devolvería XML o un error genérico, nunca tu maquetado.
- Revisá el header
cf-workero cualquier header custom que tu Worker agregue. Su presencia confirma que el request pasó por el Worker. - Andá al dashboard de Workers y listá las rutas (Routes) de la zona. Buscá cualquier patrón con
*que pueda solaparse con el hostname de tu R2. - Compará hostnames: ¿el patrón del Worker incluye subdominios? Un
*.example.com/*abarcamedia.example.comaunque vos pensabas solo en el sitio. - Probá con curl:
curl -I https://media.example.com/archivo.mp4. Si el content-type vuelvetext/htmlen lugar devideo/mp4, el Worker se metió en el medio.
¿Cómo resuelvo el conflicto entre el Worker wildcard y mi R2?
Hacé la ruta del Worker lo más específica posible para que no toque el subdominio de R2. Hay tres enfoques y conviene elegir según cómo tengas armado el sitio.
Opción 1: acotá el patrón de ruta del Worker
Si tu Worker solo maneja una parte del sitio, cambiá example.com/* por algo como example.com/api/* o example.com/app/*. Con eso, los requests a media.example.com dejan de coincidir con el patrón y siguen su camino hacia el custom domain de R2. Es la solución más limpia cuando el Worker no necesita cubrir todo el dominio.
Opción 2: dejá el subdominio fuera del wildcard
Si el Worker sí tiene que cubrir el sitio principal, asegurate de que su patrón apunte al apex y no a subdominios. example.com/* (sin *. adelante) captura el dominio raíz pero no media.example.com. Revisá que no tengas un segundo patrón wildcard más amplio arrastrado de otra config. Lo explicamos a fondo en comparar Cloudflare con AWS.
Opción 3: manejá R2 desde el propio Worker
Si por diseño no podés separar los hostnames, atá el binding de R2 al Worker y serví los objetos desde ahí. En este patrón documentado, el Worker recibe el request, lo mapea a una key del bucket y devuelve el objeto. Más control, pero también más código para mantener y más superficie para bugs.
Checklist: confirmá que tu R2 funciona de verdad
Antes de dar por resuelto el tema, verificá cada punto en orden. Si todos dan verde y seguís con 404, el problema está en la capa de ruteo, no en R2.
- El archivo existe en el bucket con la key exacta que estás pidiendo (mayúsculas y barras incluidas).
- El acceso público o el custom domain está habilitado en la config de R2.
- El dominio personalizado figura como Active, no “Pending” ni “Initializing”.
- El registro DNS existe y está proxeado por Cloudflare.
- Ningún Worker intercepta ese hostname (el paso clave que casi nadie revisa).
- La respuesta es binaria: content-type
video/mp4,image/webpo lo que corresponda, jamástext/html.
Errores comunes al combinar Workers y R2
Estos son los tropiezos que se repiten y cómo evitarlos:
- Asumir que R2 tiene prioridad: es al revés. El Worker responde primero. Corrección: revisá las rutas de Worker antes de tocar cualquier cosa de R2.
- No auditar rutas viejas: ese wildcard lo configuraste hace meses y lo olvidaste. Corrección: cada vez que agregás un custom domain, listá las rutas de Worker de la zona.
- Olvidar que los Workers aplican a subdominios: un
*.example.com/*abarca todo. Corrección: usá el patrón más angosto que resuelva tu caso. - Querer servir un 404 custom desde R2: si el Worker ya responde, tu página de error de R2 nunca se muestra. Corrección: primero sacá el Worker del medio, después pensá en el manejo de errores.
- Diagnosticar por el status code y no por el body: dos 404 se ven iguales en los logs. Corrección: mirá el HTML de la respuesta, ahí está la pista.
¿Conviene usar Cloudflare Pages en lugar de un Worker manual?
Si solo necesitás servir contenido estático más los objetos de R2, Cloudflare Pages maneja la precedencia de rutas de forma más previsible que un Worker armado a mano. Con Pages evitás justamente el escenario de este artículo: el wildcard que se traga subdominios sin que te enteres. El Worker manual te da control total, pero ese control incluye la libertad de pegarte un tiro en el pie con un patrón demasiado amplio.
Para todo lo que sea hosting web, dominios AR y despliegue de sitios sin pelearte con la infra, donweb.com te resuelve la parte de alojamiento mientras Cloudflare queda para CDN y edge. Cada herramienta en su lugar.
Preguntas Frecuentes
¿Por qué mi dominio personalizado de R2 devuelve 404?
Casi siempre porque un Worker con ruta wildcard está interceptando la solicitud antes de que R2 la reciba. Las rutas de Worker tienen precedencia sobre los custom domains de R2 en el mismo hostname, así que el Worker responde su propia 404 y R2 nunca ve el request. Revisá el body del error: si tiene el estilo de tu sitio, es un Worker.
¿Qué tiene precedencia, un Worker wildcard o un R2 custom domain?
El Worker, sin excepción. En el mismo hostname, la ruta de Worker se evalúa y ejecuta antes que el dominio personalizado de R2. Por eso un patrón como *.example.com/* se come las solicitudes destinadas a tu subdominio de media aunque el custom domain figure como Active. Cubrimos ese tema en detalle en cómo R2 se compara con S3.
¿Cómo diagnostico si un Worker intercepta mi R2?
Mirá el contenido de la respuesta 404 en DevTools o con curl -I. Si el content-type vuelve text/html con el diseño de tu sitio en lugar del archivo binario esperado, respondió un Worker. Después andá al dashboard de Workers y buscá rutas con asterisco que solapen ese hostname.
¿Cómo evito que el wildcard del Worker rompa R2?
Usá el patrón de ruta más específico posible, como example.com/api/* en lugar de example.com/*, y evitá los patrones que arrancan con *. si tu R2 vive en un subdominio. Así los requests a media.example.com dejan de coincidir con el Worker y llegan al custom domain de R2.
¿Qué es Cloudflare R2 y en qué se diferencia de AWS S3?
Cloudflare R2 es un servicio de almacenamiento de objetos compatible con la API de S3 que no cobra por egreso de datos, a diferencia de AWS S3, donde la transferencia de salida tiene costo. Esa ausencia de cargos por egreso es la razón principal por la que se usa para servir media a alto volumen.
Conclusión
El 404 de tu R2 no está en R2. Cuando el bucket, los archivos, el custom domain y el DNS figuran todos sanos y aun así cada request muere en 404, dejá de revisar R2 y andá derecho al dashboard de Workers. La regla que hay que grabarse: las rutas de Worker tienen precedencia sobre los custom domains de R2, y un wildcard configurado hace meses puede estar comiéndose subdominios enteros en silencio.
El fix es de cinco minutos una vez que sabés dónde mirar: acotá el patrón del Worker o sacá el subdominio de media de su alcance. El diagnóstico, en cambio, te puede costar un día si buscás del lado equivocado (le pasó al autor del caso original, y por eso lo documentó). La próxima vez que un subdominio de archivos te devuelva HTML con tu propio diseño, ya sabés: alguien contestó antes que R2.
Fuentes
- Cloudflare Workers Routes – documentación oficial sobre patrones y precedencia de rutas
- Cloudflare R2 Troubleshooting – guía oficial de resolución de problemas de R2
- Lucian Tudor en dev.to – el caso real de las 60 files con 404
- Cloudflare Community – hilo sobre custom domain de R2 con error 404
- Lei Mao – patrón de Worker como proxy para acceso a bucket R2






