App Proxy

Stuck on "Verifying you are human"? Fixing Cloudflare Challenge Loops Behind a Proxy

If the page loads and only the check fails, bandwidth is not your problem. A Cloudflare challenge is a verdict, not a download. It weighs the reputation of your exit IP, whether the request chain stays consistent from issue to solve, and whether the browser can run the script at all. Break any one of those and you get the spinner that never resolves, Verifying you are human that never finishes, a refresh that lands you back on the challenge, or a re-prompt a few minutes into a conversation.

Scope: the web challenge loop only. Region rejections and unsupported_country live in accessing ChatGPT behind a proxy. Account-side trouble—unusual activity warnings, forced phone verification, restricted accounts—is risk control, covered in AI accounts and exit IP risk. Pages that never load at all belong in proxy on but sites not opening. Nothing here is about bypassing a challenge.

The shortest path to the answer

Three questions, in order, decide where you spend the next ten minutes:

  1. Does the page load at all? No → path problem, not a challenge problem; go to sites not opening.
  2. On the same node, does a private window work while the normal window loops? Yes → it is the browser environment; jump to the browser section.
  3. Does every Cloudflare site challenge, or only the AI sites? Everywhere → the exit IP itself is bad; change the node. Only AI sites → add the challenge host to the pinned group.

Most wasted afternoons come from answering these out of order—people swap a fifteenth node while the real culprit was an extension.

Identify which challenge you are looking at

The two surfaces fail for different reasons. A full-page challenge takes over the window, typically reading "Verifying you are human. This may take a few seconds.", with an error code and a Ray ID underneath; passing it issues a clearance cookie for the zone. An embedded widget is Turnstile, moving through "Verify you are human" → "Verifying..." → "Success!", and it shows up around logins, signups, and message sends.

Do not dismiss the error code and Ray ID. After Cloudflare's 2026 redesign the detail moved into an in-page troubleshooting modal—for the clock case it states outright that your device must be set to the correct date and time for your time zone. Reading that line first beats guessing at nodes.

Four layers, each with its own tell

Layer What it looks like How to confirm
Exit IP reputation Same node challenges every time, on every Cloudflare site A less crowded exit improves it immediately
Mid-challenge IP change Click, spin, back to the challenge—forever Repeated trace calls return more than one IP
DNS / TLS path Only some AI sites challenge; everything else is fine Resolution and actual egress disagree
Browser environment Another browser or a private window just works Fixed by disabling extensions, clock sync, or allowing cookies

Work them in that order. Exit IP reputation is the common one: datacenter ranges, nodes shared by dozens of subscribers, addresses with a scraping history—all start with a low score. There is very little you can do from the browser side on an IP like that. You change the exit.

The IP changed mid-challenge—the layer everyone misses

The challenge must be issued and solved from the same exit IP. Cloudflare states it plainly: when the solve request for a Managed Challenge comes from a different IP than the one the challenge was issued to, the solve is not valid and you may hit a challenge loop (How Challenges work). That single sentence explains most "I clicked it twenty times" reports. The clicking was fine; the identity submitting it had changed.

Proxy clients manufacture that condition through two separate routes. The temporal one: a url-test group re-picks on a timer and fallback moves on when a health check fails, so one probe cycle landing between your click and the result post is enough to change your identity; load-balance spreads connections across exits by design. Group behaviour and how to configure it is covered in exit IP and account risk control.

The spatial one is sneakier: a challenge is never a single request. The full-page flow fetches a script, posts a result, and redirects back, and the Turnstile script is served from challenges.cloudflare.com—a hostname that shares no suffix with chatgpt.com or claude.ai, so domain-based routing rules never pick it up for free. The page body leaves through node A while the challenge script leaves through node B. Your exit never "changed", yet issue and solve genuinely came from two addresses, and the loop is identical. This is why pinning a single node sometimes still fails: the site got pinned, the challenge host did not.

Clearance validity is also tied to client characteristics such as the User-Agent and TLS fingerprint. That part is not spelled out in the docs, but it points the same way: the engine trusts the client that solved the challenge, not merely the IP it came from. The practical consequence is concrete—changing your UA or spoofing a fingerprint mid-session breaks things exactly like changing IP does, which is the browser section below.

Five-minute reading: is your egress stable?

Start with the measurement that carries the most information. Switch the group to manual selection, pin one node, then check the exit repeatedly:

curl -s https://www.cloudflare.com/cdn-cgi/trace | grep -E "^(ip|loc|sni)="

for i in 1 2 3 4 5 6; do
  curl -s https://www.cloudflare.com/cdn-cgi/trace | grep "^ip="
  sleep 2
done

The threshold is unambiguous. Six identical ip= values means egress is stable, so move on to IP reputation or the browser. Two or more distinct values means fix the config before you touch a single cookie. loc= tells you where the exit lands, and sni=encrypted means that connection negotiated ECH.

Then confirm whether you were challenged or simply never got through:

curl -sI https://chatgpt.com | grep -iE "cf-ray|cf-mitigated|^HTTP"

A cf-mitigated: challenge header says the path works and you were handed a challenge—latency numbers are irrelevant at that point. No response or a timeout is a different failure entirely; go back to sites not opening.

One more cheap split, and it takes two minutes: on the same node and the same browser, load a few unrelated sites that also sit behind Cloudflare. Everything challenges — the exit IP itself scores badly enough to trigger checks broadly, and changing exits is the only action that helps. Only the AI sites challenge — the exit is not blacklisted, those sites simply run stricter policies, so another node in the same region is usually enough. Another browser or a private window is fine — it is the browser environment, the node is innocent, and further node hopping is wasted time.

Those three outcomes call for three completely different fixes, so do not skip this step. Plenty of afternoons get burned swapping a fifteenth node when the culprit was an extension.

Clash Verge: the challenge host must share the group

How to build a manual group with a fixed exit, and how to keep it from being overwritten on subscription update, is already covered in exit IP and account risk control. What matters for challenge loops is the domain list itself—most people route only the site apex into their pinned group, so the page body and the challenge widget leave through two different exits. Put these lines in the profile's Edit Rules prepend area:

  # host that serves the challenge / Turnstile script
  - DOMAIN-SUFFIX,challenges.cloudflare.com,AI-Fixed
  # page body and static assets: miss one and part of the page routes elsewhere
  - DOMAIN-SUFFIX,chatgpt.com,AI-Fixed
  - DOMAIN-SUFFIX,oaistatic.com,AI-Fixed
  - DOMAIN-SUFFIX,oaiusercontent.com,AI-Fixed
  - DOMAIN-SUFFIX,claude.ai,AI-Fixed
  - DOMAIN-SUFFIX,claudeusercontent.com,AI-Fixed

challenges.cloudflare.com is the critical line. Both full-page challenges and Turnstile widgets load their script from it and post results back through it, and because it shares no suffix with the site domains, no domain-based rule brings it along by accident. Two follow-ups: the rules must sit ahead of the bulk rules your subscription ships, or they never match; and existing connections do not migrate after an edit, so quit and reopen the browser—or kill those rows in the connections view—before you reload the challenge.

Background probing is the other overlooked piece. If a scheduled latency test fires mid-challenge, your exit can move underneath you. While debugging, disable auto-switching on this path, or at minimum stretch the probe interval and set lazy: true so idle groups stop testing themselves.

DNS only has to satisfy one condition here—resolution must not contradict actual egress. With fake-ip enabled, Clash handles names internally and that is usually fine. Trouble comes from running system DNS, browser DoH, and Clash DNS simultaneously, where the browser holds one set of addresses while Clash routes on another. Keep one path while debugging, then restore them one at a time; details in fake-ip and DNS and DNS configuration.

Tun versus system proxy is not about strength, it is about blast radius. For a browser-only challenge, system proxy plus a pinned node is the shortest path and the easiest to diagnose: every browser request leaves through the mixed port and one group covers it all. Tun captures the whole machine, which is what you want when desktop apps need the tunnel too (see Claude.ai and Claude Desktop), at the cost of a much wider match surface—scatter those domains across groups and inconsistent egress gets more likely, not less. Under Tun, confirm in the connections view that these hostnames share one node before you blame Cloudflare. Basics in Tun mode.

The browser side you can actually repair

Reach this layer only after egress is stable, and work it in order. Open a private window first—if private mode works and the normal window loops, it is an extension or stale site data, and you can stop guessing. Check the clock next: a device a few minutes off is enough for the token to read as expired, and toggling automatic time off and back on is the quickest repair. Then allow cookies: clearance lives in a cookie, so a site with cookies blocked—or a browser blocking cross-site cookies globally—can never store the pass, which shows up precisely as "passed, then straight back to the challenge".

Be selective about extensions. Cloudflare says outright that challenges do not support extensions which modify the browser's User-Agent value or Web APIs such as Canvas and WebGL—UA switchers, canvas blockers, and assorted anti-fingerprint add-ons all qualify, and community threads keep landing on exactly those. Ad blockers and privacy tools can block the challenge script outright. Also stop stacking proxies: a VPN extension on top of your client gives you two egress layers and doubles the odds of a mismatch.

Clear data for that one site rather than wiping your history—the lock icon in the address bar gets you to that site's cookies and storage—then close the tab and reopen. Refreshing a page that is already holding a bad cookie proves nothing, because the state you are retrying with is the broken part.

Two rarer but real causes. Security suites and parental-control software that inspect HTTPS alter the TLS layer, which behaves exactly like a fingerprint extension; swapping browsers will not help, you have to exclude that software temporarily and compare. And a challenge page cached by something in the path leaves you clicking a page that expired—a hard reload that bypasses cache is more on-target there than clearing cookies.

What this article will not do

No bypass instructions, and no recommendations for auto-solvers, solver services, or fingerprint-spoofing add-ons. They all work by pretending to be a different client, the downside when detected ranges from harsher challenges to a restricted account, and third-party spoofing packages have repeatedly shipped malware.

The useful work is on the other side: stable egress, a normal browser environment, a request chain that stays consistent—so legitimate traffic stops being misjudged. If three nodes in three regions all fail, stop. Your subscription's exit quality is the ceiling, and changing provider or node pool beats flipping more switches. See choosing a provider and latency testing. Client builds: download center.

Stable egress beats a faster node

Challenge loops are caused by egress that moves, not by latency. Install Clash Verge Rev from the download center, pin the AI domains to one node as shown below, then run the checks.