{"id":"IL-0408","org":"OpenRouter","date":"2026-02-17","docs":[],"title":{"en":"OpenRouter's API returned 500s and false 401 \"User not found\" errors when its API key cache dropped and came back empty","ko":"API 키 조회 캐시가 비워진 채 돌아와 OpenRouter API 가 두 번에 걸쳐 500 과 401 \"User not found\" 오류를 냈다"},"domain":["ai-infra","database"],"impact":{"scope":"All OpenRouter API endpoints and the chatroom: on 17 February about 20% of API requests failed, then 80-90%; on 19 February partial failures, then near-total downtime","users":"A portion of OpenRouter users","region":"unknown"},"review":{"written_by":"session","reviewed_at":null,"reviewed_by":null},"lessons":{"en":"Answering an infrastructure failure with an authentication error made customers debug API keys that were fine, so error codes have to say what actually failed. Attributing the first outage to a concurrent denial-of-service attack, because the caching dependency had always been reliable, left the real fault in place until it recurred two days later. OpenRouter holds that redundancy against failures in its dependencies is its own responsibility, not the provider's.","ko":"OpenRouter 는 원인이 외부 의존성의 고장이었더라도, 의존성이 고장 나도 버티는 중복 구성을 갖추는 일은 자기 책임이라고 밝혔다. 실제로는 인프라 문제인데 인증 오류를 낸 것이 고객에게 큰 혼란을 줬고, 고객이 자기 쪽 잘못이 아닌 문제를 디버깅하게 만들었다. 첫 장애 때 같은 시각의 서비스 거부 공격을 원인으로 보고 대응 순서를 정했기 때문에 같은 고장이 이틀 뒤 다시 났다."},"related":[],"sources":[{"url":"https://openrouter.ai/blog/announcements/openrouter-outages-on-february-17-and-19-2026/","kind":"blog","archived":"https://web.archive.org/web/20261029031222/https://openrouter.ai/blog/announcements/openrouter-outages-on-february-17-and-19-2026/"}],"summary":{"en":"OpenRouter checks API keys against its database through an external caching layer from a third-party provider; normally the cache answers almost every authentication check and only a small fraction of requests reach the database. In both incidents the caching layer dropped all of its connections to the database and started returning errors, which failed about 20% of requests with 500. Within minutes the cache recovered and reconnected, but all cached entries had been invalidated, so every incoming request needed a fresh database lookup. The database could not handle the sudden spike in lookups, and the resulting timeouts reached users as 401 \"User not found\" errors.\n\nOn 17 February an internal alert fired at 5:28 AM, a minute after impact began. A concurrent denial-of-service attack was taken for the cause and blocked with WAF rules at 5:50, and service came back when the cache had fully repopulated at 6:05, 38 minutes after the start. The caching provider began investigating after the first incident, but diagnosing and fixing the failure took time. On 19 February the cache failed the same way at 7:36 AM without an attack, the alert fired at 7:38, and service was restored when the cache had repopulated at 8:11, after 35 minutes. OpenRouter then deployed targeted protections within hours. The changes it has deployed are circuit breakers that detect caching layer failures and refill a cold cache in a controlled way instead of letting every request fall through to the database at once, and a 503 instead of a 401 when an authorization lookup cannot complete. The caching provider deployed fixes for the failure mode behind both incidents.","ko":"OpenRouter 는 API 키를 데이터베이스에서 빠르게 조회하려고 외부 캐시 계층을 쓴다. 평소에는 인증 확인의 대부분을 이 캐시가 처리하고, 데이터베이스로 직접 가는 요청은 일부뿐이다. 2026년 2월 17일 05:27 UTC 에 이 캐시 계층이 데이터베이스와의 연결을 모두 끊고 오류를 내기 시작했고, 요청의 약 20% 가 500 오류로 실패했다. 05:40 UTC 에 캐시가 다시 연결했지만 저장된 항목이 모두 무효가 돼 있어서 들어오는 요청마다 데이터베이스를 새로 조회해야 했다. 데이터베이스는 갑자기 몰린 조회를 감당하지 못했고, 그 타임아웃이 사용자에게 401 \"User not found\" 오류로 나갔다. 실패율은 80~90% 까지 올랐고, 06:05 UTC 에 캐시가 다시 다 채워지면서 서비스가 돌아왔다.\n\n2월 17일에는 서비스 거부 공격이 같은 시각에 커지고 있었다. 이 캐시 의존성이 그동안 매우 안정적이었기 때문에 OpenRouter 는 처음에 장애를 공격 탓으로 보고 그 공격 경로를 막는 데 힘을 쏟았다. 캐시 제공업체도 첫 장애 직후 조사를 시작했지만 원인을 찾아 고치는 데 시간이 걸렸다. 2월 19일 07:36 UTC 에 공격 없이 같은 캐시 고장이 다시 났고, 같은 순서로 500 오류에서 401 오류로 번진 뒤 08:11 UTC 에 캐시가 다시 채워지며 복구됐다. 이때 진짜 원인이 드러났고, OpenRouter 는 몇 시간 안에 이 고장을 겨냥한 보호 장치를 배포했다.\n\nOpenRouter 는 캐시 계층의 고장을 감지해 피해 범위를 줄이는 circuit breaker 를 넣었다. 이 circuit breaker 는 캐시가 비었을 때 모든 요청이 한꺼번에 데이터베이스로 가지 않도록 캐시를 통제된 방식으로 다시 채운다. 인프라 문제로 인가 조회를 끝내지 못하면 401 대신 503 을 내도록 바꿨다. 캐시 제공업체도 두 장애를 일으킨 고장 방식을 고쳤다."},"trigger":{"en":"The third-party caching layer in front of API key lookups dropped all of its connections to OpenRouter's database and began returning errors.","ko":"API 키 조회 앞에 둔 외부 캐시 계층이 데이터베이스와의 연결을 모두 끊고 오류를 내기 시작했다. 캐시는 몇 분 안에 다시 연결했지만 저장된 항목이 모두 무효가 된 상태였다."},"severity":"unknown","symptoms":["high-error-rate","service-unavailable","database-overloaded"],"timeline":{"detected_after":"1m","resolved_after":"38m"},"date_kind":"incident","detection":{"en":"An internal alert fired one minute after impact began on 17 February, at 5:28 AM UTC, and two minutes after it began on 19 February, at 7:38 AM UTC, and the response team came online to investigate.","ko":"OpenRouter 는 내부 알림으로 장애를 알았다. 2월 17일에는 영향이 시작되고 1분 뒤인 05:28 UTC 에, 2월 19일에는 2분 뒤인 07:38 UTC 에 알림이 울렸고 대응 팀이 바로 조사를 시작했다."},"components":["cache","database"],"root_cause":"dependency-failure","remediation":[{"text":{"en":"Deployed WAF rules to block the denial-of-service attack running at the same time on 17 February","ko":"2월 17일 05:50 UTC 에 장애와 함께 진행되던 서비스 거부 공격을 찾아 WAF 규칙으로 막았다."}}],"action_items":[{"text":{"en":"Add circuit breakers that detect caching layer failures, limit their blast radius and repopulate a cold cache in a controlled way","ko":"캐시 계층의 고장을 감지하고 피해 범위를 줄이는 circuit breaker 를 넣었다. 이 circuit breaker 는 캐시가 비었을 때 모든 요청이 한꺼번에 데이터베이스로 가지 않게 캐시를 통제된 방식으로 다시 채운다."}},{"text":{"en":"Return 503 instead of 401 when an authorization lookup cannot complete because of an infrastructure problem","ko":"인프라 문제로 인가 조회를 끝내지 못하면 401 대신 503 service unavailable 을 내도록 바꿨다. 고객이 진짜 인증 문제와 일시적인 인프라 문제를 구별할 수 있게 하려는 것이다."}},{"text":{"en":"The caching provider fixes the failure mode that caused both incidents","ko":"캐시 제공업체가 두 장애를 일으킨 고장 방식을 고치는 수정을 배포했다."}},{"text":{"en":"Roll out a fallback caching mechanism so OpenRouter survives even extended downtime of the caching layer","ko":"캐시 계층이 오래 내려가도 버틸 수 있도록 대체 캐시 구성을 곧 배포한다."}}],"contributing":["warm-cache-dependency","overlapping-failures"],"recurrence_of":null,"symptoms_text":{"en":"At 5:27 AM UTC on 17 February 2026 part of OpenRouter's users started getting 500 errors on all API endpoints, and from 5:40 AM many requests failed with 401 \"User not found\" errors although their API keys were valid. The chatroom was degraded at the same time. The same pattern came back at 7:36 AM UTC on 19 February.\n\nOn 17 February about 20% of API requests failed between 5:27 and 5:40 AM UTC, and 80-90% failed between 5:40 and 6:05 AM. On 19 February failures were partial between 7:36 and 7:42 AM and close to total between 7:42 and 8:11 AM. Both times the caching layer had logged occasional errors with no user-facing impact beforehand, from 5:20 AM and from 7:16 AM.\n\nThe 401 errors sent some customers into debugging their own API key configurations when nothing on their side was wrong. They were database timeouts during API key lookups, returned to users as an authentication failure.\n\nOn 17 February a denial-of-service attack was ramping up at the moment the caching layer failed. Because such attacks can cause cascading problems across the stack, and because the caching dependency had historically been extremely reliable, OpenRouter first attributed the outage to the attack, deployed WAF rules against it at 5:50 AM and put its effort into hardening against that attack vector. Only when the same cache failure recurred on 19 February without an attack did the real root cause become clear.","ko":"OpenRouter 사용자 일부가 모든 API 엔드포인트에서 500 오류를 받았고, 몇 분 뒤에는 401 \"User not found\" 오류를 받았다. 2026년 2월 17일 05:27 UTC 부터 38분, 2월 19일 07:36 UTC 부터 35분 동안 같은 장애가 났고, 그때마다 내부 알림이 1~2분 안에 울렸다. 이 시간 동안 chatroom 도 제대로 동작하지 않았다.\n\n두 번 모두 고장 직전에 API 키 조회용 캐시 계층이 사용자에게는 영향이 없는 오류를 이따금 남기기 시작했다. 2월 17일에는 05:20 UTC 부터, 2월 19일에는 07:16 UTC 부터였다.\n\n장애는 두 단계로 번졌다. 2월 17일에는 05:27 UTC 부터 05:40 UTC 까지 API 요청의 약 20% 가 500 오류로 실패했고, 05:40 UTC 부터 06:05 UTC 까지는 실패율이 80~90% 였다. 2월 19일에는 07:36 UTC 부터 07:42 UTC 까지 일부 요청이 실패했고, 07:42 UTC 부터 08:11 UTC 까지는 서비스가 거의 전부 멈췄다.\n\n401 \"User not found\" 오류는 인증 문제가 아니라 인프라 문제에서 나왔다. 데이터베이스가 몰려든 키 조회를 처리하지 못해 타임아웃이 났고, 이 타임아웃이 사용자에게 401 로 전달됐다. 그래서 일부 고객은 자기 쪽에 잘못이 없는데도 API 키 설정을 디버깅하느라 시간을 썼다.\n\n2월 17일에는 같은 시각에 서비스 거부 공격이 커지고 있었다. 엔지니어는 05:50 UTC 에 이 공격을 찾아 WAF 규칙으로 막았고, 처음에는 장애를 이 공격 때문이라고 보고 그 공격 경로를 막는 일을 먼저 했다. 2월 19일에 공격 없이 같은 캐시 고장이 다시 나고서야 진짜 원인이 드러났다."},"updated_at":"2026-11-14T12:34:05.874642Z","url":"https://benchlet.com/incidentlib/app/cases/IL-0408","org_slug":"openrouter"}