Many websites use Cloudflare to “offload” their servers, since it’s the largest content delivery network (CDN) in the world. At the same time, Cloudflare can handle website protection against DDoS attacks and act as an intermediary. In this mode, the service works like a filter: it carefully analyzes incoming traffic, detects and blocks suspicious connections. This is what’s known as a WAF (Web Application Firewall).
This article focuses on the Cloudflare error with code 1010. We’ll explain what it means, when it appears, and how to avoid or bypass it when scraping.
Important! Cloudflare 1010 Error is returned not by the target website you’re trying to scrape, but by the intermediary service — Cloudflare. This means it is acting as a firewall and blocking suspicious connections.
The Cloudflare error with code 1010 (Access Denied, Bad IP) is an access error caused by an incorrect or unsuitable IP address.
Most likely, this error occurs because the IP address you used to connect to the site (either your own or that of a proxy server) has previously been flagged for suspicious activity and has failed the security check.
The concept of security can be very broad, so below we’ll look at the causes of Cloudflare error 1010 from several angles.
Without going too deep into the details, in most cases Cloudflare 1010 is shown to visitors because one of the following protection rules is triggered:
These rules can be configured and triggered by:
What symptoms indicate that a Cloudflare 1010 error has occurred? It’s quite simple. In most cases, you’ll recognize it by a special placeholder page.
The browser will display something like:
To fix error code 1010, a regular user can go through the following steps and try to eliminate potential issues:
If that doesn’t help, turn off all browser extensions and try accessing the site with a “clean” profile.
Clear the cookies for the website where you’re getting the Cloudflare 1010 error.
If the error appears only on a specific device, check whether that device’s TLS/SSL certificates are up to date (they may be outdated, especially if you’re using an operating system version that hasn’t been updated for a long time), or scan your drive for viruses/unwanted software (it may be sending automated requests to the target site, which Cloudflare detects and responds to with error code 1010).
Check your system time settings, and even better, enable automatic time synchronization using network time servers.
Try disabling your antivirus software, firewalls, and ad blockers. In some cases, they can modify HTTP requests and break their integrity (especially when they “cut out” ads and trackers).
Perfect proxies for accessing valuable data from around the world.
Keep in mind that Cloudflare’s job when filtering unwanted traffic for a website is precisely to efficiently weed out all the “junk” connections generated by bots and scrapers. They don’t bring any real value to the site and sometimes are outright harmful.
Therefore, if you encounter Cloudflare 1010 error while scraping, it means your scraper is not good enough yet to bypass Cloudflare’s protection rules. Or the problem lies in the type/quality of your proxies.
Typical reasons that lead to this error include:
It’s not that some specific programming construct directly causes error code 1010. This is not a bug in your code or script. It’s a problem with the scraper’s overall logic and behavior: the script is being detected and blocked. It would be naïve to expect Cloudflare’s developers to publish a straightforward checklist on how to prevent or bypass Cloudflare error 1010.
So, first of all, your scraper must be able to handle Cloudflare 1010 errors so it can promptly detect them and either stop or trigger special bypass / fallback algorithms.
Second, you need to go through the possible causes of Cloudflare error 1010 and carefully rethink your scraper’s logic. Sometimes it’s enough to fix a single issue, but in other cases you may have to rewrite the entire scraper from scratch because it’s conceptually outdated and easily detected by Cloudflare’s anti-bot protection. Based on the most likely causes outlined above, we can offer the following recommendations for quick response.
The exact technical setup can vary from project to project. Unfortunately, there is no universal recipe.
We love Python, so our sample scripts are written in it:
import random
import time
import requests
import telegram
from selenium.webdriver.common.action_chains import ActionChains
import undetected_chromedriver as uc
from selenium.webdriver.common.by import By
# -------------------------------
# CONFIG
# -------------------------------
TARGET_URLS = [
"https://example.com/page1",
"https://example.com/page2"
]
BACKCONNECT_PROXIES = [
"proxy1.example.com:1234",
"proxy2.example.com:1234",
"proxy3.example.com:1234"
]
BROWSER_PROFILES = [
{"user_agent": "Mozilla/5.0 ... Chrome/121.0", "cookies": "cookies/profile1.txt"},
{"user_agent": "Mozilla/5.0 ... Firefox/119.0", "cookies": "cookies/profile2.txt"},
{"user_agent": "Mozilla/5.0 ... Safari/605.1.15", "cookies": "cookies/profile3.txt"}
]
REQUEST_TIMEOUT = 20
RETRY_LIMIT = 3
TG_TOKEN = "YOUR_TELEGRAM_TOKEN"
TG_CHAT_ID = "YOUR_CHAT_ID"
bot = telegram.Bot(TG_TOKEN)
# -------------------------------
# UTILITIES
# -------------------------------
def send_telegram_message(text):
bot.send_message(chat_id=TG_CHAT_ID, text=text)
def get_random_proxy():
return random.choice(BACKCONNECT_PROXIES)
def random_delay():
time.sleep(random.uniform(3, 5))
def is_cloudflare_1010(response):
if response.status_code == 403 and "1010" in response.text:
return True
return False
# -------------------------------
# HEADLESS SELENIUM LOADER
# -------------------------------
def load_with_selenium(url, profile):
proxy = get_random_proxy()
options = uc.ChromeOptions()
options.headless = False # remains visible, but the window can be hidden
options.add_argument(f"--proxy-server=http://{proxy}")
options.add_argument(f"--user-agent={profile['user_agent']}")
driver = uc.Chrome(options=options)
# cookies download (if any)
try:
with open(profile["cookies"], "r", encoding="utf-8") as f:
cookies = f.read().split("\n")
for c in cookies:
if "=" in c:
name, value = c.split("=", 1)
driver.add_cookie({"name": name.strip(), "value": value.strip()})
except:
pass
driver.get(url)
time.sleep(3)
# Action imitation
actions = ActionChains(driver)
# mouse move
for _ in range(3):
actions.move_by_offset(
random.randint(-50, 50),
random.randint(-50, 50)
).perform()
time.sleep(0.3)
# scroll
for _ in range(3):
driver.execute_script("window.scrollBy(0, arguments[0]);", random.randint(200, 700))
time.sleep(0.5)
html = driver.page_source
driver.quit()
return html
# -------------------------------
# REQUESTS LOADER
# -------------------------------
def load_with_requests(url, profile):
proxy = get_random_proxy()
proxies = {
"http": f"http://{proxy}",
"https": f"http://{proxy}"
}
headers = {
"User-Agent": profile["user_agent"],
"Accept": "text/html,application/xhtml+xml",
"Accept-Language": "en-US,en;q=0.9"
}
# cookies download
cookies_dict = {}
try:
with open(profile["cookies"], "r", encoding="utf-8") as f:
for line in f:
if "=" in line:
k, v = line.split("=", 1)
cookies_dict[k.strip()] = v.strip()
except:
pass
response = requests.get(
url,
headers=headers,
cookies=cookies_dict,
proxies=proxies,
timeout=REQUEST_TIMEOUT
)
return response
# -------------------------------
# MAIN PARSE FUNCTION
# -------------------------------
def process_url(url):
print(f"Processing: {url}")
attempts = 0
while attempts < RETRY_LIMIT:
attempts += 1
profile = random.choice(BROWSER_PROFILES)
random_delay()
try:
response = load_with_requests(url, profile)
if is_cloudflare_1010(response):
print("Cloudflare 1010 detected. Switching to Selenium...")
html = load_with_selenium(url, profile)
return html
if response.status_code == 200:
return response.text
else:
print(f"Error {response.status_code}, attempt {attempts}")
except Exception as e:
print(f"Request error: {e}, attempt {attempts}")
# if everything is bad — send to Telegram
send_telegram_message(f" Error when processing URL after {RETRY_LIMIT} attempts:\n{url}")
return None
# -------------------------------
# ENTRY POINT
# -------------------------------
if __name__ == "__main__":
for url in TARGET_URLS:
html = process_url(url)
if html:
print(f"Loaded: {len(html)} bytes")
else:
print("Failed.")
Don’t forget to install the required libraries and wait for the headless browsers for Selenium to finish loading.
What the script does:
The script itself doesn’t contain any specific parsing logic, but you can add it on your own or borrow from our examples in related blog posts. For HTML parsing we recommend using BeautifulSoup.
Cloudflare-related issues don’t come from the target website (the one you’re trying to scrape), but from Cloudflare’s own protection mechanisms. This service acts as a kind of web antivirus (or advanced firewall) and can analyze a large number of connection attributes: browser fingerprints, IP history, user behavior and more. Getting past Cloudflare’s defenses can be quite difficult, and the service is not limited to error code 1010, you may encounter many other access errors. The most annoying format is being forced to solve a CAPTCHA. We have a separate article on how to deal with Cloudflare protection. If you see an error, it means you’ve failed Cloudflare’s automatic security check. For regular users who aren’t involved in web scraping, it’s usually enough to disable their VPN or proxy — in most cases, Cloudflare error 1010 is triggered by them. But there may be other reasons as well, all of which we’ve covered above.
Not always. If Cloudflare’s security system is unhappy with your browser profile (digital fingerprint), changing the IP won’t help. Although yes, the root cause is often the low quality of the IP address. Another case where IP rotation won’t save you is when the IP belongs to an ASN subnet or to an IP pool of a specific provider that has been flagged as undesirable. In that situation, rotating IPs within the same subnet will keep leading to Cloudflare error 1010.
Indirectly. If Cloudflare considers a client suspicious, it may either show a CAPTCHA or immediately return code 1010. However, the error itself means an access denial at the rules level, not a mandatory CAPTCHA challenge.
Yes. Sometimes Cloudflare’s cloud-based protection rules change dynamically: there may be A/B tests, temporary geoblocking, occasional traffic filters, or an increase in the “suspicion” score after several rapid requests. After some time, access may be restored.
So, even though the error code 1010 and its general cause are clearly defined, 1010 can be triggered by a combination of many factors — from a genuinely bad IP address to “suspicious” user activity (when signs of automation and scraping are detected from that IP).
You can’t always get rid of the error just by quickly changing (rotating) your IP address. However, the quality and “naturalness” of the IP are at the core of any further attempts to bypass the issue.
You can find high-quality proxies with us. Froxy offers over 10 million residential and mobile IPs with targeting down to the city and ISP level, and pricing based on prepaid traffic packages.