{"id":"IL-0283","org":"Cloudflare","date":"2025-11-18","docs":[],"title":{"en":"Cloudflare's core proxy returned HTTP 5xx across its network after loading an oversized Bot Management feature file","ko":"Cloudflare 네트워크 전체에서 코어 프록시가 Bot Management 피처 파일을 읽다 실패해 사이트 방문자들이 HTTP 5xx 오류 페이지를 받았다"},"domain":["database","networking"],"impact":{"scope":"Core CDN and security services returned HTTP 5xx errors and the majority of core traffic stopped flowing; Turnstile, Workers KV, Access, dashboard login and parts of Email Security were also affected, and on the old FL proxy all traffic got a bot score of zero","users":"Internet users visiting Cloudflare customers' sites and Cloudflare customers","region":"Cloudflare's whole network"},"review":{"written_by":"session","reviewed_at":null,"reviewed_by":null},"lessons":null,"related":[],"sources":[{"url":"https://blog.cloudflare.com/18-november-2025-outage/","kind":"blog","archived":"https://web.archive.org/web/20261107100308/https://blog.cloudflare.com/18-november-2025-outage/"}],"summary":{"en":"Every request to Cloudflare passes the HTTP and TLS layer, then the core proxy FL, then Pingora for cache lookups or origin fetches. The core proxy applies each customer's configuration through modules, one of which is Bot Management: a machine learning model gives every request a bot score, using a feature configuration file that is refreshed every few minutes and published to the entire network. A query on a ClickHouse cluster generates this file every five minutes. In that cluster, distributed tables in the database default read the underlying tables of each shard in the database r0, and queries to the distributed tables ran through a shared system account; work was under way to run them under the initial user accounts so limits and grants could be applied per user.\n\nAt 11:05 UTC a permissions change made users' access to the r0 tables explicit. The feature file query read name and type from system.columns for the table 'http_requests_features' without filtering on the database name, on the old assumption that only the default database would be returned. After the change it also returned the r0 columns, more than doubling the rows and so the features in the file. The proxy preallocates memory for features and limits them to 200, against about 60 in use, so when the file with more than 200 features reached the servers, the FL2 Rust code hit an unhandled error and panicked, and the proxy returned 5xx. Since only the updated ClickHouse nodes produced bad files, the network failed and recovered every few minutes until all nodes produced the bad file.\n\nAt 13:05 Cloudflare used internal bypasses so Workers KV and Access fell back to a prior proxy version, which reduced their impact and the errors of services that rely on Workers KV. By 13:37 the team was confident the Bot Management file was the trigger and worked on restoring a last-known-good version. At 14:24 it stopped the creation and propagation of new feature files and confirmed recovery with the old file; at 14:30 a correct file was deployed globally, by inserting a known good file into the distribution queue and forcing a restart of the core proxy, and core traffic largely flowed normally. A second period of reduced dashboard availability, from 14:40 to 15:30, came from a backlog of login attempts and retries and ended when control plane concurrency was scaled. Remaining services that had entered a bad state were restarted, and 5xx volume returned to normal at 17:06. Cloudflare called it its worst outage since 2019.","ko":"Cloudflare 의 코어 프록시는 요청마다 봇 점수를 매기는 Bot Management 모듈을 돌린다. 이 모듈의 머신러닝 모델은 피처 설정 파일을 입력으로 받는다. 이 파일은 몇 분마다 새로 만들어 네트워크 전체에 퍼뜨린다. 피처 파일은 ClickHouse 클러스터에서 5분마다 도는 쿼리가 만들었는데, 이 쿼리는 system.columns 에서 http_requests_features 테이블의 열을 고르면서 데이터베이스 이름으로 거르지 않았다. 2025년 11월 18일 11:05 UTC 에 Cloudflare 는 분산 쿼리를 공유 시스템 계정 대신 쿼리를 처음 낸 사용자 계정으로 돌리려는 작업의 하나로 권한 변경을 클러스터에 차례로 적용했다. 이 변경은 사용자들이 r0 데이터베이스의 하위 테이블 메타데이터도 볼 수 있게 권한을 명시했다. 그러자 쿼리 결과에 r0 의 열까지 섞여 피처 파일의 행이 두 배가 넘게 늘었다.\n\n프록시는 성능을 위해 피처용 메모리를 미리 잡아 두었고, 피처 수 한도를 200 으로 정해 두었다. 실제로 쓰는 피처는 약 60 개였다. 200 개가 넘는 피처가 담긴 파일이 서버에 퍼지자 FL2 의 Rust 코드가 처리하지 않은 오류로 패닉을 냈고, 봇 모듈에 기대는 모든 트래픽이 HTTP 5xx 오류를 받았다. 옛 프록시 FL 에서는 오류 대신 모든 트래픽의 봇 점수가 0 이 됐다. 업데이트된 ClickHouse 노드에서 쿼리가 돌 때만 잘못된 파일이 나왔으므로 5분마다 좋은 파일과 나쁜 파일이 번갈아 퍼졌다. 네트워크가 회복과 실패를 되풀이하자 팀은 처음에 공격을 의심했다. 상태 페이지가 우연히 함께 내려간 것도 이 의심을 키웠다. 코어 프록시에 기대는 Workers KV 와 Access 도 장애를 겪었다. Turnstile 은 뜨지 않았고, Workers KV 와 Turnstile 을 쓰는 대시보드도 영향을 받았다.\n\n13:05 에 Workers KV 와 Access 를 이전 버전 프록시로 우회시켜 영향을 줄였다. 팀은 Bot Management 설정 파일이 원인이라고 보고 14:24 에 새 파일의 생성과 배포를 멈췄으며, 알려진 정상 파일을 배포 큐에 손으로 넣고 코어 프록시를 강제로 재시작했다. 14:30 에 주된 영향이 풀렸다. 쌓인 로그인 시도로 느려진 대시보드는 15:30 무렵 컨트롤 플레인 동시성을 늘려 되살렸다. 나쁜 상태에 빠진 나머지 서비스들을 재시작해 17:06 에 모든 서비스가 정상으로 돌아왔다. Cloudflare 는 2019년 이후 가장 나쁜 장애였다고 밝혔다."},"trigger":{"en":"At 11:05 UTC Cloudflare deployed a ClickHouse access control change that made users' existing implicit access to the underlying tables in the r0 database explicit, so the metadata of those tables became visible in system tables such as system.columns. The change was being rolled out gradually across the cluster.","ko":"11:05 UTC 에 Cloudflare 는 ClickHouse 사용자들이 암묵적으로 갖고 있던 r0 데이터베이스 하위 테이블 접근 권한을 명시적으로 주는 변경을 배포했다. Bot Management 피처 파일을 만드는 쿼리는 데이터베이스 이름으로 거르지 않았고, 이 변경 뒤 쿼리 결과에 중복 행이 섞이기 시작했다."},"severity":"unknown","symptoms":["high-error-rate","service-unavailable","high-latency","response-quality-degraded"],"timeline":{"detected_after":"3m","resolved_after":"5h 38m"},"date_kind":"incident","detection":{"en":"The first automated test detected the issue at 11:31 UTC, three minutes after the first errors on customer HTTP traffic at 11:28. Manual investigation started at 11:32 and the incident call was created at 11:35.","ko":"11:31 UTC 에 첫 자동 테스트가 문제를 감지했고, 11:32 에 수동 조사가 시작됐으며, 11:35 에 장애 대응 통화가 열렸다."},"components":["database","cdn"],"root_cause":"config-change","remediation":[{"text":{"en":"Bypassed the core proxy for Workers KV and Access so they fell back to a prior proxy version, which reduced their impact","ko":"13:05 UTC 에 Workers KV 와 Cloudflare Access 를 내부 우회 경로로 돌려 이전 버전의 코어 프록시를 쓰게 했다. 이전 버전에도 같은 문제가 있었지만 영향이 작았다."}},{"text":{"en":"Stopped the automatic creation and deployment of new Bot Management feature files","ko":"14:24 UTC 에 새 Bot Management 설정 파일의 자동 배포를 멈췄다."}},{"text":{"en":"Inserted a known good feature file into the distribution queue and deployed it globally","ko":"알려진 정상 피처 파일을 피처 파일 배포 큐에 손으로 넣었다."}},{"text":{"en":"Forced a restart of the core proxy","ko":"코어 프록시를 강제로 재시작했다. 14:30 UTC 에 주된 영향이 풀렸다."}},{"text":{"en":"Scaled control plane concurrency to clear the backlog of dashboard logins","ko":"쌓인 로그인 시도와 재시도로 느려진 대시보드를 컨트롤 플레인 동시성을 늘려 15:30 UTC 무렵 되살렸다."}},{"text":{"en":"Restarted the remaining services that had entered a bad state","ko":"나쁜 상태에 빠진 나머지 서비스들을 재시작했고, 17:06 UTC 에 5xx 오류량이 평소로 돌아왔다."}}],"action_items":[{"text":{"en":"Harden the ingestion of Cloudflare-generated configuration files the same way as user-generated input","ko":"Cloudflare 가 직접 만든 설정 파일도 사용자 입력처럼 엄격하게 검증한 뒤 받아들인다."}},{"text":{"en":"Enable more global kill switches for features","ko":"기능을 네트워크 전체에서 끌 수 있는 킬 스위치를 더 늘린다."}},{"text":{"en":"Stop core dumps and other error reports from being able to overwhelm system resources","ko":"코어 덤프나 다른 오류 보고가 시스템 자원을 다 써 버리지 못하게 한다."}},{"text":{"en":"Review the failure modes for error conditions across all core proxy modules","ko":"모든 코어 프록시 모듈이 오류가 났을 때 어떻게 실패하는지 검토한다."}}],"contributing":["assumption-unverified","partial-rollout","no-staged-rollout","no-config-tests","overlapping-failures","retry-storm"],"recurrence_of":null,"symptoms_text":{"en":"From about 11:20 UTC on 18 November 2025, Cloudflare's network started failing to deliver core traffic, and Internet users visiting Cloudflare customers' sites got an error page that pointed to a failure inside Cloudflare's network. The volume of HTTP 5xx responses served by the network jumped far above its normal low baseline.\n\nThe errors came from the core proxy, called FL or Frontline, for all traffic that depended on its Bot Management module. On the new proxy engine, FL2, the module panicked with \"thread fl2_worker_thread panicked: called Result::unwrap() on an Err value\" and requests failed with 5xx. Customers still on the old FL engine saw no errors, but every request got a bot score of zero, so rules that block bots produced large numbers of false positives. CDN response latency also rose sharply, because debugging and observability systems spent large amounts of CPU adding debugging information to uncaught errors. Workers KV returned significantly elevated 5xx errors, Access authentication failed for most users, Turnstile failed to load, and most users could not log in to the dashboard.\n\nAt first the failures came and went: the network recovered for a while and then failed again. The feature file was regenerated every five minutes by a query on a ClickHouse cluster that was being updated gradually, and only runs on the updated part produced a bad file, so good and bad files alternated across the network. In the end every ClickHouse node produced the bad file and the network stayed in the failing state.\n\nBecause this fluctuation was very unusual for an internal error, the team first suspected a hyper-scale DDoS attack, possibly a continuation of the recent high-volume Aisuru DDoS attacks. Cloudflare's status page, which is hosted entirely off Cloudflare's infrastructure, went down at the same time by coincidence, and some responders took it as a sign that an attacker was targeting both. The first symptom the team investigated was a degraded Workers KV response rate, and from 11:32 to 13:05 it tried traffic manipulation and account limiting to bring Workers KV back to normal.","ko":"11:20 UTC 부터 Cloudflare 네트워크가 내보내는 HTTP 5xx 오류가 치솟았다. 고객 사이트를 찾은 인터넷 사용자들은 Cloudflare 네트워크 안에서 실패했다는 오류 페이지를 봤다.\n\n오류는 한동안 줄었다가 다시 늘기를 되풀이했다. 내부 오류로는 아주 드문 모습이어서 팀은 처음에 초대형 DDoS 공격을 의심했다. 내부 장애 대응 채팅방에서는 최근 이어진 대규모 Aisuru DDoS 공격의 연장일 수 있다고 걱정했다. 결국 모든 ClickHouse 노드가 잘못된 파일을 만들게 되자 오르내림이 멈추고 실패 상태로 굳었다.\n\nCloudflare 인프라와 완전히 떨어져 호스팅되는 상태 페이지도 같은 시기에 내려가 오류 메시지를 띄웠다. 나중에 우연으로 밝혀졌지만, 일부 팀원은 공격자가 시스템과 상태 페이지를 함께 노린다고 믿게 됐다.\n\n처음 눈에 띈 증상은 Workers KV 의 응답률 저하와 오류 증가였고, 다른 Cloudflare 서비스들이 그 영향을 받는 것처럼 보였다. 팀은 11:32 부터 13:05 까지 트래픽 조정과 계정 제한으로 Workers KV 를 정상 수준으로 되돌리려 했다.\n\n새 프록시 엔진 FL2 를 쓰는 고객은 HTTP 5xx 오류를 받았다. 옛 엔진 FL 을 쓰는 고객은 오류는 받지 않았지만 모든 트래픽의 봇 점수가 0 으로 매겨져, 봇 차단 규칙을 둔 곳에서 오탐이 크게 늘었다. FL2 는 thread fl2_worker_thread panicked: called Result::unwrap() on an Err value 패닉을 내며 5xx 오류를 냈다.\n\nTurnstile 이 뜨지 않아 활성 세션이 없는 사용자는 대시보드에 로그인하지 못했다. Access 는 대부분의 사용자에게 인증 실패 오류 페이지를 보였다. 디버깅 시스템과 관측 시스템이 잡히지 않은 오류에 디버깅 정보를 자동으로 덧붙이느라 CPU 를 많이 썼고, 그 때문에 CDN 응답 지연도 크게 늘었다."},"updated_at":"2026-11-14T12:33:53.784653Z","url":"https://benchlet.com/incidentlib/app/cases/IL-0283","org_slug":"cloudflare"}