Cloudflare error 1020 means a firewall rule written by the website's owner matched your request and blocked it. Error 1015 means you hit the owner's rate limit. Error 1010 means the owner blocked your browser signature, and 1006, 1007 and 1008 mean your IP address is banned. A 403 page that says "Just a moment" or "checking your browser" is a challenge, not an error code, and it carries the header cf-mitigated: challenge. In every case the site's owner configured the block; Cloudflare only enforces it.

That shapes the fix. Changing IP helps with some of these and does nothing for others, and for all of them the owner's intent is the same: they do not want this traffic as it is. The sections below take each code from Cloudflare's documentation, show how to tell them apart in code, and list the fixes that work without fighting the site.

If the error came from your proxy rather than the target, start with our proxy error codes guide instead: 407 and 502 are proxy problems, and none of the codes below are.

Cloudflare error codes at a glance

What you seeUsual statusWhat firedDoes a new IP change it?First fix
Error 1020, "Access denied"403An owner's firewall (WAF) ruleOnly if the rule keyed on IP, country or networkFind out what the rule matches; ask the owner
Error 1015, "You are being rate limited"429An owner's rate limiting ruleBriefly, then the new IP is limited tooSlow down per IP and per site
Error 1010, browser signature403Browser Integrity CheckNoSend a normal, consistent client
Error 1006, 1007, 1008, "IP banned"403An owner's IP blockYes, which is why the owner will not be pleasedAsk the owner to review it
"Just a moment", "checking your browser"403A challenge from a bot or security ruleRarelyUse the site's API, a real browser where permitted, or ask
Plain 403, server: cloudflare, no code403Often the origin or another vendor behind CloudflareDependsRead the body; it may not be Cloudflare's block at all

Cloudflare error 1020: access denied by a firewall rule

Cloudflare's error 1020 page says it plainly: access "is denied by a Cloudflare firewall rule", and the rule is the Cloudflare customer's. Owners write these rules in the WAF against almost any request property: country, ASN (the network the IP belongs to), path, query string, User-Agent, headers, and on Enterprise plans with Bot Management, the TLS fingerprint and bot score.

That is why a 1020 behaves differently from site to site:

  • Keyed on network type. Many sites block hosting ASNs. A datacenter IP gets 1020; the same request from a consumer-carrier IP does not.
  • Keyed on country. A site that only serves one market blocks the rest. An IP in the right country passes.
  • Keyed on your client. A rule matching python-requests in the User-Agent, or a missing header, blocks you on every IP you own.
  • Keyed on path. Some sites block automated access to search, login or checkout pages and leave the rest open.

The quickest test is to send the same request from two different IP types and with a normal browser. If the browser on your own connection gets through and your script does not, the rule is about your client, not your address.

Cloudflare's advice for visitors is to contact the owner with a screenshot, and for owners to find the block in Security Events by Ray ID or IP. Every 1020 page shows the Ray ID; so does the cf-ray response header. Keep it: it is what makes an allowlisting request actionable.

Cloudflare error 1015: you are being rate limited

Error 1015 means the owner has a rate limiting rule and you crossed it. Cloudflare's rate limiting rules block with a 429 by default, and each rule has its own counting window and block duration, so there is no universal "safe" rate and no fixed wait.

Counting depends on the owner's plan. On Free and Pro plans a rule counts per IP only. Enterprise customers with advanced rate limiting can count by headers, cookies, ASN, country, path, or JA3/JA4 fingerprint as well. So spreading the same traffic over more IPs may lift a 1015 for a while on a small site, and do nothing on a large one that counts per session or per fingerprint.

The fix that holds on both is the boring one: send less.

  1. Stop at the first 1015 and wait. Retrying during the block extends it.
  2. Honour Retry-After when present.
  3. Pace per site and per IP, with jitter. Our guide to scraping without getting blocked has a per-host throttle and backoff code you can reuse.
  4. Cache and send conditional requests, so pages that have not changed cost nothing.

Cloudflare error 1010: blocked on your browser signature

Error 1010 means "the owner of this website has banned your access based on your browser's signature". The feature behind it is usually Browser Integrity Check, which looks for HTTP headers commonly abused by spammers and challenges clients with no User-Agent or a non-standard one.

A proxy cannot help: the signature is in your request, and the proxy forwards it unchanged. The fix is to send what a normal client sends. Set a real User-Agent, send Accept and Accept-Language, and keep them consistent with the rest of your client. Our explainer on TLS fingerprinting covers the handshake-level half of the signature and why a proxy never changes it.

Cloudflare errors 1006, 1007 and 1008: your IP is banned

Cloudflare documents 1006, 1007 and 1008 together: "Access Denied: Your IP address has been banned." The owner blocked your address, or a range containing it, and Cloudflare support cannot override it.

This is the one case where a different IP changes the result mechanically. It is also the case where the owner's intent is least ambiguous: they looked at traffic from that address and said no. Rotating around an explicit ban turns a technical question into a relationship problem, and in some disputes courts have treated continued access after being told to stop as the key fact. Our guide to whether web scraping is legal covers that ground. The better move is to ask why, fix it, and ask to be let back in.

One honest exception: shared addresses. If you are on a residential line, a VPN or a shared proxy IP, someone else may have earned the ban. A dedicated static IP is yours alone, so its reputation is your own doing.

The 403 challenge page and "checking your browser"

A page titled "Just a moment..." or saying Cloudflare is checking your browser is a challenge page. Cloudflare returns a full HTML page that runs checks in the browser (or, for some types, asks a person to click); when they pass, the browser gets a cf_clearance cookie tied to that visitor and device, and continues.

For a script, three facts matter:

  1. Detect it by header. Cloudflare documents that challenge responses carry cf-mitigated: challenge, always with text/html, whatever you asked for. In practice the status is a 403. A JSON client that gets HTML here is being challenged, not served an error.
  2. The challenge is the owner's decision. It comes from a rule, often driven by bot score, and the owner put it there to keep automated clients out of that page.
  3. We do not help defeat it. No guide from us covers solving or bypassing challenges or CAPTCHAs. If the data behind the challenge is essential, the options are below.

How to tell a WAF rule from rate limiting from bot management

Log what you got, not only the status code. This classifier reads the headers and body the way the sections above describe. It uses only requests and a regular expression:

import os
import re
import sys

import requests

PROXY = os.environ.get("PROXY_URL")
PROXIES = {"http": PROXY, "https": PROXY} if PROXY else None

CODE = re.compile(r"error(?:\s+code)?:?\s*(1\d{3})\b", re.I)
MEANING = {
    "1020": "blocked by a firewall rule the site owner wrote",
    "1015": "rate limited by the site owner's rule",
    "1010": "blocked on browser signature (Browser Integrity Check)",
    "1006": "your IP is banned by the site owner",
    "1007": "your IP is banned by the site owner",
    "1008": "your IP is banned by the site owner",
}


def classify(resp):
    via_cloudflare = "cf-ray" in resp.headers
    if resp.headers.get("cf-mitigated") == "challenge":
        return "Cloudflare challenge page (bot or security rule)"
    match = CODE.search(resp.text[:20000])
    if via_cloudflare and match:
        code = match.group(1)
        return f"Cloudflare error {code}: {MEANING.get(code, 'see Cloudflare docs')}"
    if resp.status_code == 429:
        return "429 rate limit" + (" (Cloudflare rule or origin)" if via_cloudflare else "")
    if via_cloudflare and resp.status_code == 403:
        return "403 with no Cloudflare code: likely the origin or another bot vendor"
    if resp.ok:
        return "OK"
    return f"HTTP {resp.status_code}"


if __name__ == "__main__":
    resp = requests.get(sys.argv[1], proxies=PROXIES, timeout=20)
    print(resp.status_code, resp.headers.get("cf-ray"), "->", classify(resp))

We checked it on 2026-09-29 against sample 1020, 1015, 1010 and challenge responses, and against live Cloudflare-fronted sites through a local authenticating proxy. One live result is worth knowing: several large sites answered a plain requests call with a 403, server: cloudflare and a cf-ray header, but no 1xxx code and no cf-mitigated. One body was the single word "Forbidden"; another asked us to enable JavaScript. server: cloudflare only tells you the site uses Cloudflare as its CDN. The block may come from the origin or from another bot-protection vendor sitting behind it, and the Cloudflare error docs will not explain it.

To see what Cloudflare sees of your request, most Cloudflare-fronted sites answer /cdn-cgi/trace with plain text. Through our local proxy it reported the proxy's exit ip, the country as loc, http=http/1.1 and uag=python-requests/2.34.2: a quick check that your proxy is in use and what your client is announcing.

What a proxy changes and what it does not

Signal Cloudflare rules can useChanged by switching proxy IP?
IP address and IP-based rate countersYes
Country and ASN (hosting vs consumer carrier)Yes, by choosing the IP
IP reputation, including bans earned by other users of a shared IPYes
User-Agent, headers, cookiesNo
TLS fingerprint (JA3/JA4) and HTTP/2 settingsNo
Request rate per session or per fingerprintNo
JavaScript checks in a challengeNo

A proxy gives you control over the network half. That is legitimate and useful: a price monitor that must see a German storefront needs a German IP, and a site that blocks hosting ranges for good reasons may still serve an ISP address. Our ISP proxies are registered to consumer carriers and sold one IP at a time, and you choose country, region, city and carrier at checkout. But a proxy is not a disguise for a client the site has already refused on other grounds.

Legitimate fixes, in the order to try them

  1. Look for an API or a data feed. Many sites behind Cloudflare publish one. It is faster, cheaper, stable, and nobody blocks it for being used.
  2. Slow down. Most 1015s and many challenges are about rate. Pace per IP, back off with jitter, cache.
  3. Send an honest, consistent client. A real User-Agent that matches your TLS and HTTP/2 behaviour, normal headers, cookies kept within a session. Consistency matters more than disguise.
  4. Match the network to the job. If the rule is about geography or hosting ranges and the data is public, an IP in the right country and network type is a fair answer. Measure before you scale; our residential, ISP and datacenter comparison helps pick.
  5. Ask for allowlisting. Email the owner with the Ray ID, what you collect, how often, and the IPs you will use. Owners can allowlist by IP in Cloudflare's IP Access Rules or skip a rule for you. This works only with addresses that do not change, which is the practical case for static ISP or datacenter IPs over a rotating pool.
  6. Become a verified bot. If you run a crawler at scale, Cloudflare's verified bots directory accepts bots that identify themselves honestly (a Web Bot Auth signature, a published IP list with a stable User-Agent, or reverse DNS) and behave well, including obeying robots.txt and keeping request rates reasonable.

And if none of that works, the site has answered. Our allowed-use policy permits public data collection as long as you respect the target's rate limits and do not degrade its service; it does not make a refused target into an allowed one.