FlareSolverr was, for years, the default answer to "how do I get past Cloudflare from a scraper?" You ran it as a small proxy server, POSTed a URL to it, and it launched a real browser, sat through the challenge, and handed you back cookies and HTML. It was the workhorse behind countless Jackett, Prowlarr, and Sonarr setups, and behind a lot of home-grown scrapers too.
In 2026 it increasingly does not work. The symptoms are familiar: the request times out, you get back the challenge page instead of the content, the logs say "Challenge not detected", or a Turnstile widget on the page is simply never solved. This post explains honestly why FlareSolverr fails on modern Cloudflare, where it still works fine, the real alternatives, and how to migrate to a managed API when you want a single HTTP call instead of a browser to babysit.
What FlareSolverr actually does
FlareSolverr is a self-hosted proxy server, usually run in Docker. You send it an HTTP request like {"cmd": "request.get", "url": "https://target.com"}, and under the hood it drives a real Chromium browser (via undetected-chromedriver / Selenium) to load the page. When Cloudflare serves the legacy "I'm Under Attack Mode" (IUAM) interstitial — the "Checking your browser... Just a moment" page — FlareSolverr waits for the browser to run the challenge JavaScript, collects the resulting cf_clearance cookie, and returns the cookies plus the page HTML and User-Agent to you.
The key design assumption is that loading the page in a real browser and waiting is enough. For the old IUAM challenge, it was: the browser executed the JS-math puzzle, the cookie dropped, and you were through. That assumption is exactly what broke.
Why FlareSolverr stopped working on modern Cloudflare
Cloudflare's protection moved on, and FlareSolverr's browser-and-wait approach no longer covers what the wall throws at it. There are four overlapping reasons it fails today:
- Turnstile — Cloudflare's CAPTCHA replacement runs a non-interactive proof-of-work plus browser-API probes and only then issues a cf-turnstile-response token. FlareSolverr loads the page but has no logic to produce that token, so a Turnstile-gated form or page is never cleared — it just sits there.
- Managed Challenge — modern challenges dynamically pick proof-of-work / proof-of-space, behavioral signals, and web-API probing based on the visitor. The plain Chromium that FlareSolverr drives is detectable, so the challenge frequently never clears and you get the interstitial back instead of your content.
- Stalled maintenance — keeping a browser-automation tool invisible to Cloudflare is a constant cat-and-mouse job, and FlareSolverr's development has been slow and intermittent. Each Cloudflare update that the project does not chase tends to break another batch of targets.
- Heavy resource use and fragility — every request spins up a headful/headless Chromium. That is hundreds of megabytes of RAM per worker, slow cold starts, frequent timeouts under load, and a process that crashes or hangs far more than a plain HTTP client would.
Typical FlareSolverr error symptoms in 2026
If you are debugging, the failure usually shows up as one of these. Recognizing which one tells you whether it is fixable or fundamental:
- It returns the challenge page — the response "solution" contains the "Just a moment..." / "Checking your browser" HTML instead of the real content. Cloudflare served a challenge the embedded browser could not clear.
- Timeouts — the request hangs and eventually errors out (often around the maxTimeout you set). Under modern managed challenges the browser waits for a cookie that never drops.
- "Challenge not detected" — FlareSolverr loaded the page, did not recognize a challenge it knows how to handle, and returned early. Common when the wall is Turnstile or a v3-style challenge it was not built for.
- Turnstile unsolved — the page loads but the Turnstile widget stays unverified and any form submission fails, because there is no token-solving step in the pipeline.
When FlareSolverr still works fine
To be fair: FlareSolverr is not useless, and you should not rip it out reflexively. If your target still serves the old IUAM JS-math interstitial — and some smaller or older sites do — a real browser loading the page and waiting still clears it, and FlareSolverr does exactly that with zero per-request cost.
So the honest test is: open the target in a browser. If you see a brief "Just a moment..." page that clears on its own with no checkbox and no visible widget, FlareSolverr (or a maintained fork) will probably handle it. If you see a Turnstile checkbox, an interactive widget, or a managed-challenge page that loops or stalls, no amount of FlareSolverr tuning will reliably get you through — that is a different class of challenge.
FlareSolverr alternatives in 2026, compared honestly
No single tool wins outright — it depends on which Cloudflare layer is blocking you. Here is a fair breakdown of the realistic options:
- Maintained forks (e.g. Byparr) — drop-in-ish FlareSolverr replacements that track Cloudflare changes more actively and swap in newer stealth browser stacks. If you like the proxy-server model, this is the lowest-friction upgrade — but it is still a browser you host, and it still struggles with Turnstile and tough managed challenges.
- nodriver — the modern successor to undetected-chromedriver, with minimal CDP traces. Good when you genuinely need JavaScript to run and want fewer automation fingerprints. Trade-offs: heavy CPU/RAM, slow startup, fragile at scale, and still not a guarantee against managed challenges or Turnstile.
- curl_cffi / curl-impersonate — impersonate a real browser's TLS and HTTP/2 fingerprint, lightweight and fast. Perfect when the only obstacle is TLS fingerprinting and the site is not actually issuing a JS challenge. But they execute no JavaScript and solve no CAPTCHA, so they cannot pass a managed challenge or Turnstile alone.
- Managed solving API — you POST the target details to an HTTP endpoint and get back a valid token or cf_clearance cookie. No browser fleet, no Docker container to babysit, no chasing Cloudflare updates. You trade a small per-solve cost for reliability and zero infrastructure.
When a managed API is the right call, and why NSLSolver
If you are clearing old IUAM pages on a couple of low-traffic targets, keep FlareSolverr or move to a maintained fork like Byparr — it is free and good enough. But if you are hitting Turnstile or managed challenges, running this in production, or tired of a Docker container that eats RAM and breaks on every Cloudflare update, hosting a browser is the wrong layer to be fighting at.
NSLSolver is a developer API built for exactly that. It handles Cloudflare Turnstile, Cloudflare Challenge (managed / JS challenge), and Kasada behind a single HTTP contract — no browser to host, no infra to maintain. Turnstile solves average around 250 ms with a 99.9% success rate, billing is per successful solve so failed solves are free, and pricing is pay-as-you-go: Turnstile at $0.40 per 1,000 solves, Cloudflare Challenge at $0.50 per 1,000, and Kasada at $1.50 per 1,000. New accounts get 100 free requests at signup — no card and no crypto needed to start.
The mental shift is simple: instead of running a browser proxy that loads the page and hopes the challenge clears, you make one HTTP call and get back exactly the artifact you need — a cf_clearance cookie and matching User-Agent for a challenge, or a token for Turnstile — then replay it on your own requests session.
import requests
API = "https://api.nslsolver.com"
HEADERS = {"X-API-Key": "nsl_YOUR_API_KEY"}
TARGET = "https://target-site.com"
# 1) Ask NSLSolver to pass the Cloudflare managed/JS challenge
# (replaces the FlareSolverr request.get round-trip)
resp = requests.post(
f"{API}/solve",
headers=HEADERS,
json={
"type": "challenge",
"url": TARGET,
"proxy": "http://user:pass@host:port",
},
)
data = resp.json()
# 2) Replay the clearance cookie + User-Agent on your own session
session = requests.Session()
session.cookies.update(data["cookies"]) # dict keyed by cf_clearance
session.headers["User-Agent"] = data["user_agent"] # snake_case field
# 3) Now scrape normally — the request looks like a cleared browser
html = session.get(TARGET).text
print(html[:500])Solving Turnstile tokens directly
If the wall is a Turnstile widget rather than a full interstitial — for example a protected login or signup form that FlareSolverr leaves unverified — request a token instead. POST the widget's site_key and the page url, and use the returned token as the cf-turnstile-response value when you submit the form.
That is the whole migration. You stop running the Docker proxy, keep your existing requests session, and let the API handle the part FlareSolverr was never able to brute-force with a browser.
import requests
API = "https://api.nslsolver.com"
HEADERS = {"X-API-Key": "nsl_YOUR_API_KEY"}
resp = requests.post(
f"{API}/solve",
headers=HEADERS,
json={
"type": "turnstile",
"site_key": "0x4AAAAAAA...",
"url": "https://target-site.com",
},
)
token = resp.json()["token"] # e.g. "0.AAAA..."
# Submit the token as cf-turnstile-response
payload = {"cf-turnstile-response": token, "username": "me", "password": "secret"}
requests.post("https://target-site.com/login", data=payload)