El 5 de diciembre de 2025, a las 08:47 UTC (todas las horas de este blog son UTC), una parte de la red de Cloudflare comenzó a experimentar fallos importantes. El incidente se resolvió a las 09:12 (unos 25 minutos de impacto total), cuando se restablecieron por completo todos los servicios.
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 particular se vea afectado como se describe a continuación, deben darse varios factores.
El problema no fue causado, ni directa ni indirectamente, por un ciberataque contra los sistemas de Cloudflare ni por 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 generalizada en el sector que se reveló esta semana en React Server Components.
Cualquier interrupción de nuestros sistemas es inaceptable y somos conscientes de que hemos vuelto a desconectar Internet tras el incidente del 18 de noviembre. La semana que viene 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 emitidos por nuestra red durante el periodo 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 ofrece a los clientes protección contra cargas malintencionadas, lo que permite su detección y bloqueo. Para ello, el proxy de Cloudflare almacena en búfer el contenido del cuerpo de la solicitud HTTP en la memoria para su análisis. Hasta hoy, el tamaño del búfer se estableció en 128 KB.
Como parte de nuestro trabajo continuo para proteger a los clientes que utilizan React contra una vulnerabilidad crítica, CVE-2025-55182, comenzamos a aumentar el tamaño de nuestro búfer a 1 MB, el límite predeterminado permitido por las aplicaciones Next.js, con el fin de garantizar la protección del mayor número posible de clientes.
Este primer cambio se implementó utilizando nuestro sistema de implementación gradual. Durante el proceso, observamos que nuestra herramienta interna de prueba del WAF no admitía el aumento del tamaño del búfer. Dado que esta herramienta de prueba interna no era necesaria en ese momento y no afectaba al tráfico de clientes, realizamos un segundo cambio para desactivarla.
Este segundo cambio para desactivar nuestra herramienta de prueba de WAF se implementó utilizando nuestro sistema de configuración global. Este sistema no realiza implementaciones graduales, sino que propaga los cambios en cuestión de segundos a todo el conjunto de servidores de nuestra red, y está en proceso de revisión tras la interrupción que experimentamos el 18 de noviembre.
Desafortunadamente, en nuestra versión FL1 del proxy, en determinadas circunstancias, el segundo cambio de desactivación de nuestra herramienta de prueba de reglas WAF provocó un estado de error que dio lugar a que se enviaran 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 dio lugar a un error en nuestro módulo de reglas, lo que provocó 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 ocasionó que se enviaran errores de código HTTP 500.
El problema se identificó poco después de que se aplicara el cambio y se revirtió a las 09:12, tras lo cual 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 finales 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 que utiliza nuestra Red China tampoco se vio afectado.
El error del entorno de ejecución
El sistema de conjuntos de reglas de Cloudflare consta de conjuntos de reglas que se evalúan en cada solicitud que entra en nuestro sistema. Una regla consta de un filtro que selecciona tráfico y una acción que aplica un efecto a ese tráfico. Las acciones típicas son "bloquear", "registrar" u "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 automática 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 automática recibe información de nuestro sistema de configuración global mencionado en las secciones anteriores. Hemos utilizado este sistema de desconexión automática en varias ocasiones en el pasado para mitigar incidentes, y 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 seguridad a una regla con una acción de "ejecutar". Cuando se activó el interruptor automático, 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", exista el objeto "rule_result.execute". 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.
Se trata de un error evidente en el código, que había pasado desapercibido durante muchos años. Este tipo de error de código se evita en los lenguajes con sistemas de tipos fuertes. En nuestra sustitución de este código en nuestro nuevo proxy FL2, escrito en Rust, el error no se produjo.
¿Qué ocurre con los cambios realizados tras el incidente del 18 de noviembre de 2025?
Hace dos semanas, el 18 de noviembre de 2025, realizamos un cambio no relacionado que provocó un incidente similar de mayor duración en la disponibilidad. En ambos casos, una implementación destinada a mitigar un problema de seguridad para nuestros clientes se propagó a toda nuestra red, lo que provocó errores para casi la totalidad de nuestra base de clientes.
Hemos hablado directamente con cientos de clientes tras ese incidente y hemos comunicado nuestros planes para realizar cambios que eviten que actualizaciones puntuales causen un impacto tan generalizado como este. Creemos que estos cambios habrían ayudado a evitar el impacto del incidente de hoy, pero, lamentablemente, 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 concreto, los proyectos que se describen a continuación deberían ayudar a mitigar el impacto de este tipo de cambios:
Implementaciones y versiones mejoradas: al igual que implementamos el software de forma gradual con una estricta validación del estado, los datos utilizados para la respuesta rápida ante amenazas y la configuración general deben contar con 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.
Funciones optimizadas de Break Glass: garantiza que las operaciones críticas puedan seguir realizándose ante tipos adicionales de fallos. Esto se aplica tanto a los servicios internos como a todos los métodos estándar de interacción con el panel de control de Cloudflare que utilizan todos los clientes de Cloudflare.
Gestión de errores "Fail-Open": como parte del esfuerzo de resiliencia, estamos reemplazando la lógica de fallos duros aplicada incorrectamente en todos los componentes críticos del panel de datos de Cloudflare. Si un archivo de configuración está dañado o fuera de rango (por ejemplo, excede los límites de las funciones), el sistema registrará el error y volverá a un estado conocido como válido o pasará el tráfico sin puntuarlo, en lugar de descartar las solicitudes. Es probable que algunos servicios ofrezcan al cliente la opción de fallo abierto o cerrado en determinados casos. Esto incluirá capacidades de prevención de desviaciones para garantizar que se aplique de forma continua.
Antes de que finalice la próxima semana, publicaremos un desglose detallado de todos los proyectos de resiliencia en curso, incluidos los mencionadas anteriormente. Mientras ese trabajo está en curso, bloquearemos 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 frecuencia con la que se producen, 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 a nuestros clientes y a Internet en su conjunto.
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 totalmente propagado |
08:50 | INCIDENTE declarado | Alertas automatizadas |
09:11 | Cambio revertido | Cambio de configuración revertido e inicio de la propagación |
09:12 | Fin del INCIDENTE | Reversión completamente propagada, todo el tráfico restaurado |