lichess.org
Donate

Cloudflare managed challenge blocked all lichess.org API requests from a declared bot for ~7 minutes

Hello,

On 2026-10-16, between 13:03:39 and 13:10:23 CEST (11:03:39–11:10:23 UTC), every HTTPS
request from my IP to lichess.org was answered by a Cloudflare managed challenge
instead of reaching lichess.org. The account is a declared bot (Chess26_BOT, title BOT,
token with the bot:play scope), so this is not an authentication or authorization problem:
the requests never reached your application.

Raw evidence (captured with requests, reproduced with curl and with browser
user-agents — all identical):

POST https://lichess.org/api/token/test      -> 403
GET  https://lichess.org/api/account         -> 403
GET  https://lichess.org/api/user/lichess    -> 403
GET  https://lichess.org/                    -> 403   (unauthenticated home page)
GET  https://lichess.org/api/token/test      -> 404   (only the malformed GET slipped through)

Server: cloudflare
cf-mitigated: challenge
Content-Type: text/html; charset=UTF-8
CF-RAY: a4b69d01a983c115-ZRH        (13:09, +01:00 local)
CF-RAY: a4b69d681fb4be8e-ZRH
Body: <!DOCTYPE html><html lang="en-US"><head><title>Just a moment...</title>

Timeline of the block (sampled every 10 s):

13:10:03  403  cf-mitigated=challenge  CF-RAY a4b69d681fb4be8e-ZRH
13:10:13  403  cf-mitigated=challenge  CF-RAY a4b69da6fba7e5d9-ZRH
13:10:23  200  (challenge cleared)

Impact — a rated game was lost because of this

  • Game:
    https://lichess.org/480F18jk
    — rated rapid 10+0, I played black as Chess26_BOT (2485).
  • 13:03:15 — POST /api/bot/game/480F18jk/move/f8d8 200 (move accepted).
  • 13:03:29 — the next position arrives; black has 309 s left on the clock.
  • 13:03:39 — POST /api/bot/game/480F18jk/move/a4b6 403 Cloudflare challenge.
  • The challenge cleared at 13:10:23, i.e. ~95 seconds after black's flag had already fallen
    (≈13:08:48). No client-side retry strategy could have saved the game.
  • Result: outoftime, winner white (InanisBot, 2435), ratingDiff: -26
    (rapid 2485 2459). This is the only loss in the window.
  • Also blocked: POST /api/challenge/7dCRyPRo/accept 403 at 13:07:12, so a challenge my
    bot had just accepted never became a game; and GET /api/bot/online 403, which made the
    matchmaking code report "No suitable bots found to challenge" (misleading: the bot list was
    never received).

Why this looks like a false positive

  • No VPN, no proxy, no datacenter: residential Swiss IP 194.191.194.5 (AS1836 green.ch AG).
  • Request volume at the time was about 1 request/minute (the bot was playing a single
    game, timeout bounded, User-Agent: lichess-bot/2026.1.7.1 user:Chess26_BOT).
  • No 429 was returned at any point, only 403 challenges.
  • My logs contain zero Cloudflare challenges from 2026-01-29 to 2026-04-26; this is the
    first occurrence. The block lifted on its own.
  • Lichess itself was not the one refusing: the challenge was served for the whole domain,
    including the public home page with no credentials at all.

What I would like to ask

  1. Please exclude the bot API paths (/api/bot/*, /api/token/test, /api/stream/*) from
    the Cloudflare managed challenge. A JavaScript challenge cannot be solved by an API
    client, so any challenge on those paths means an in-progress game is forfeited.
  2. If bot accounts or their IPs can be allowlisted after verification, I am happy to provide
    whatever is needed for Chess26_BOT.
  3. If challenges are unavoidable on some paths, please keep/document cf-mitigated: challenge
    (it is present today — thank you, lichess-bot can now recognise it and wait instead of
    treating it as an authorization failure). A machine-readable body instead of the JS
    challenge page would help too.
  4. If possible, a blocked-by-Cloudflare game should not be counted as a rated loss.

I can provide the full logs, more CF-RAY values, or run any diagnostic you need.

Thanks for lichess.

Chess26_BOT

Hello, On 2026-10-16, between **13:03:39 and 13:10:23 CEST (11:03:39–11:10:23 UTC)**, every HTTPS request from my IP to lichess.org was answered by a **Cloudflare managed challenge** instead of reaching lichess.org. The account is a *declared bot* (`Chess26_BOT`, title BOT, token with the `bot:play` scope), so this is not an authentication or authorization problem: the requests never reached your application. **Raw evidence** (captured with `requests`, reproduced with `curl` and with browser user-agents — all identical): ``` POST https://lichess.org/api/token/test -> 403 GET https://lichess.org/api/account -> 403 GET https://lichess.org/api/user/lichess -> 403 GET https://lichess.org/ -> 403 (unauthenticated home page) GET https://lichess.org/api/token/test -> 404 (only the malformed GET slipped through) Server: cloudflare cf-mitigated: challenge Content-Type: text/html; charset=UTF-8 CF-RAY: a4b69d01a983c115-ZRH (13:09, +01:00 local) CF-RAY: a4b69d681fb4be8e-ZRH Body: <!DOCTYPE html><html lang="en-US"><head><title>Just a moment...</title> ``` Timeline of the block (sampled every 10 s): ``` 13:10:03 403 cf-mitigated=challenge CF-RAY a4b69d681fb4be8e-ZRH 13:10:13 403 cf-mitigated=challenge CF-RAY a4b69da6fba7e5d9-ZRH 13:10:23 200 (challenge cleared) ``` **Impact — a rated game was lost because of this** - Game: https://lichess.org/480F18jk — rated rapid 10+0, I played black as `Chess26_BOT` (2485). - 13:03:15 — `POST /api/bot/game/480F18jk/move/f8d8` **200** (move accepted). - 13:03:29 — the next position arrives; black has **309 s** left on the clock. - 13:03:39 — `POST /api/bot/game/480F18jk/move/a4b6` **403 Cloudflare challenge**. - The challenge cleared at 13:10:23, i.e. **~95 seconds after black's flag had already fallen** (≈13:08:48). No client-side retry strategy could have saved the game. - Result: `outoftime`, winner white (`InanisBot`, 2435), `ratingDiff: -26` (rapid 2485 2459). This is the only loss in the window. - Also blocked: `POST /api/challenge/7dCRyPRo/accept` 403 at 13:07:12, so a challenge my bot had just accepted never became a game; and `GET /api/bot/online` 403, which made the matchmaking code report "No suitable bots found to challenge" (misleading: the bot list was never received). **Why this looks like a false positive** - No VPN, no proxy, no datacenter: residential Swiss IP **194.191.194.5** (AS1836 green.ch AG). - Request volume at the time was about **1 request/minute** (the bot was playing a single game, `timeout` bounded, `User-Agent: lichess-bot/2026.1.7.1 user:Chess26_BOT`). - No `429` was returned at any point, only `403` challenges. - My logs contain **zero** Cloudflare challenges from 2026-01-29 to 2026-04-26; this is the first occurrence. The block lifted on its own. - Lichess itself was not the one refusing: the challenge was served for the *whole domain*, including the public home page with no credentials at all. **What I would like to ask** 1. Please exclude the bot API paths (`/api/bot/*`, `/api/token/test`, `/api/stream/*`) from the Cloudflare *managed challenge*. A JavaScript challenge cannot be solved by an API client, so any challenge on those paths means an in-progress game is forfeited. 2. If bot accounts or their IPs can be allowlisted after verification, I am happy to provide whatever is needed for `Chess26_BOT`. 3. If challenges are unavoidable on some paths, please keep/document `cf-mitigated: challenge` (it is present today — thank you, lichess-bot can now recognise it and wait instead of treating it as an authorization failure). A machine-readable body instead of the JS challenge page would help too. 4. If possible, a blocked-by-Cloudflare game should not be counted as a rated loss. I can provide the full logs, more `CF-RAY` values, or run any diagnostic you need. Thanks for lichess. *Chess26_BOT*

Thanks for the report.

I recently (~20 minutes ago) excluded all /api/ endpoints from mitigation. Can you confirm all is well now?

Thanks for the report. I recently (~20 minutes ago) excluded all /api/ endpoints from mitigation. Can you confirm all is well now?

Nice
Hope it never happens again

Nice Hope it never happens again

Good luck in future bots!

Good luck in future bots!