El 5 de diciembre de 2025 a las 08:47 UTC (todas las horas de este blog corresponden a UTC), una parte de la red de Cloudflare comenzó a tener fallas importantes. El incidente se resolvió a las 09:12 (impacto total de aproximadamente 25 minutos), cuando todos los servicios se restablecieron por completo.
Un subconjunto de clientes se vio afectado, lo que representa aproximadamente el 28 % de todo el tráfico HTTP servido por Cloudflare. Para que un cliente individual se vea afectado, es necesario que se combinen varios factores, como se describe a continuación.
El problema no fue causado, ni directa ni indirectamente, por un ciberataque a los sistemas de Cloudflare o por una actividad maliciosa de ningún tipo. En cambio, se desencadenó por los cambios que se estaban realizando en nuestra lógica de análisis del cuerpo al intentar detectar y mitigar una vulnerabilidad de toda la industria divulgada esta semana en React Server Components.
Cualquier interrupción de nuestros sistemas es inaceptable, y sabemos que le hemos fallado a Internet nuevamente tras el incidente del 18 de noviembre. La semana próxima publicaremos información detallada sobre las medidas que estamos tomando para evitar que se produzcan este tipo de incidentes.
El siguiente gráfico muestra los errores HTTP 500 generados por nuestra red durante el período del incidente (línea roja en la parte inferior), en comparación con el tráfico total de Cloudflare no afectado (línea verde en la parte superior).
El Firewall de Aplicaciones Web (WAF) de Cloudflare brinda a los clientes protección contra cargas malintencionadas, permitiendo su detección y bloqueo. Para ello, el proxy de Cloudflare almacena el contenido del cuerpo de la solicitud HTTP en la memoria para su análisis. Antes de hoy, el tamaño del búfer se establecía en 128 KB.
Como parte de nuestro trabajo continuo para proteger a los clientes que usan React contra una vulnerabilidad crítica, CVE-2025-55182, comenzamos a implementar un aumento en el tamaño de nuestro búfer a 1 MB, que es el límite predeterminado permitido por las aplicaciones Next.js. Queríamos asegurarnos de proteger al mayor número posible de clientes.
Este cambio se estaba implementando mediante nuestro sistema de implementación gradual y, como parte de esta implementación, identificamos un aumento en los errores en una de nuestras herramientas internas que utilizamos para probar y mejorar las nuevas reglas WAF. Dado que se trataba de una herramienta interna, y la corrección implementada era una mejora de seguridad, decidimos deshabilitar la herramienta por el momento, ya que no era necesaria para servir o proteger el tráfico de los clientes.
La desactivación de esta función se realizó mediante nuestro sistema de configuración global. Este sistema no utiliza implementaciones graduales, sino que propaga los cambios en cuestión de segundos a toda la red y está en revisión tras la interrupción que experimentamos recientemente el 18 de noviembre.
En nuestra versión FL1 de nuestro proxy, en determinadas circunstancias, este último cambio provocó un estado de error que resultó en la entrega de códigos de error HTTP 500 desde nuestra red.
Tan pronto como el cambio se propagó a nuestra red, la ejecución del código en nuestro proxy FL1 alcanzó un error en nuestro módulo de reglas, lo que condujo a la siguiente excepción LUA:
[lua] Failed to run module rulesets callback late_routing: /usr/local/nginx-fl/lua/modules/init.lua:314: attempt to index field 'execute' (a nil value)
lo que genera errores de código HTTP 500.
El problema se identificó poco después de aplicar el cambio y se revirtió a las 09:12. Después de esto, todo el tráfico se sirvió correctamente.
Los clientes cuyos activos web se sirven a través de nuestro antiguo proxy FL1 Y que tenían implementado el conjunto de reglas administradas de Cloudflare se vieron afectados. Todas las solicitudes de sitios web en este estado devolvieron un error HTTP 500, con la pequeña excepción de algunos puntos de conexión de prueba, como /cdn-cgi/trace.
Los clientes a los que no se les aplicó la configuración anterior no se vieron afectados. El tráfico de clientes atendido por nuestra red de China tampoco se vio afectado.
El error de tiempo de ejecución
El sistema de conjuntos de reglas de Cloudflare consta de grupos de reglas que se evalúan para cada solicitud que entra en nuestro sistema. Una regla consiste en un filtro, que selecciona cierto tráfico, y una acción que aplica un efecto a ese tráfico. Las acciones típicas son “bloquear”, “registrar” o “omitir”. Otro tipo de acción es "ejecutar", que se utiliza para activar la evaluación de otro conjunto de reglas.
Nuestro sistema de registro interno utiliza esta función para evaluar nuevas reglas antes de ponerlas a disposición del público. Un conjunto de reglas de nivel superior ejecutará otro conjunto de reglas que contiene reglas de prueba. Estas eran las reglas de prueba que intentábamos desactivar.
Tenemos un subsistema de desconexión como parte del sistema de conjuntos de reglas, que está diseñado para permitir que una regla con un comportamiento incorrecto se desactive rápidamente. Este sistema de desconexión recibe información de nuestro sistema de configuración global mencionado en las secciones anteriores. En el pasado, hemos utilizado este sistema de desconexión de emergencia en varias ocasiones para mitigar incidentes. Contamos con un procedimiento operativo estándar bien definido, que se siguió en este incidente.
Sin embargo, nunca antes habíamos aplicado un interruptor de emergencia a una regla con una acción de “ejecutar”. Cuando se aplicó el interruptor de emergencia, el código omitió correctamente la evaluación de la acción de ejecución y no evaluó el subconjunto de reglas al que apuntaba. Sin embargo, se detectó un error al procesar los resultados generales de la evaluación del conjunto de reglas:
if rule_result.action == "execute" then
rule_result.execute.results = ruleset_results[tonumber(rule_result.execute.results_index)]
end
Este código espera que, si el conjunto de reglas tiene action = “execute”, el objeto “rule_result.execute” existirá. Sin embargo, dado que la regla se había omitido, el objeto rule_result.execute no existía y Lua devolvió un error al intentar buscar un valor en un valor nulo.
Este es un error simple en el código, que había existido sin detectarse durante muchos años. Este tipo de error de código lo evitan los lenguajes con sistemas de tipos fuertes. En nuestra sustitución de este código en nuestro nuevo proxy FL2, que está escrito en Rust, no se produjo el error.
¿Qué ocurre con los cambios realizados tras el incidente del 18 de noviembre de 2025?
Hicimos un cambio no relacionado que provocó un incidente de disponibilidad similar y más prolongado hace dos semanas, el 18 de noviembre de 2025. En ambos casos, una implementación para ayudar a mitigar un problema de seguridad para nuestros clientes se propagó a toda nuestra red y provocó errores en casi toda nuestra base de clientes.
Hablamos directamente con cientos de clientes después de ese incidente y compartimos nuestros planes para realizar cambios que eviten que actualizaciones individuales causen un impacto generalizado como este. Creemos que estos cambios habrían ayudado a prevenir el impacto del incidente de hoy, pero, desafortunadamente, aún no los hemos terminado de implementar.
Sabemos que es decepcionante que este trabajo aún no se haya terminado. Sigue siendo nuestra principal prioridad en toda la organización. En particular, los proyectos descritos a continuación deberían ayudar a mitigar el impacto de este tipo de cambios:
Implementaciones y control de versiones mejoradas: al igual que implementamos lentamente el software con una validación de estado estricta, los datos utilizados para la respuesta rápida a amenazas y la configuración general deben tener las mismas características de seguridad y mitigación de riesgos. Esto incluye capacidades de validación de estado y reversión rápida, entre otras cosas.
Capacidades de emergencia optimizadas: garantizar que las operaciones críticas se puedan seguir llevando a cabo frente a otros tipos de fallos. Esto se aplica tanto a los servicios internos como a todos los métodos estándar de interacción con el plano de control de Cloudflare que utilizan todos los clientes de Cloudflare.
Gestión de errores de “Fallo abierto”: como parte del esfuerzo de resiliencia, estamos reemplazando la lógica de error de fallo duro aplicada incorrectamente en todos los componentes críticos del plano de datos de Cloudflare. Si un archivo de configuración está dañado o fuera de rango (p. ej., excede los límites de las funciones), el sistema registrará el error y el sistema volverá a un estado de funcionamiento correcto conocido o pasará el tráfico sin puntuar, en lugar de descartar las solicitudes. Es probable que algunos servicios ofrezcan al cliente la opción de fallar en modo abierto o cerrado en ciertos escenarios. Esto incluirá capacidades de prevención de la deriva para garantizar que se aplique continuamente.
Antes de que finalice la próxima semana, publicaremos un desglose detallado de todos los proyectos de resiliencia en curso, incluidos los mencionados anteriormente. Mientras ese trabajo está en curso, estamos bloqueando todos los cambios en nuestra red para garantizar que tengamos mejores sistemas de mitigación y reversión antes de volver a empezar.
Este tipo de incidentes, y la proximidad con la que se agrupan, no son aceptables para una red como la nuestra. En nombre del equipo de Cloudflare, queremos disculparnos por el impacto y los inconvenientes que esto ha causado, una vez más, a nuestros clientes y a Internet en general.
Hora (UTC) | Estado | Descripción |
08:47 | Inicio del incidente | Cambio de configuración implementado y propagado a la red |
08:48 | Máximo impacto | Cambio propagado por completo |
08:50 | Incidente declarado | Alertas automatizadas |
09:11 | Se revirtió el cambio | Cambio de configuración revertido y propagación iniciada |
09:12 | Fin del incidente | Reversión totalmente propagada, todo el tráfico restaurado |