Skip to content

Troubleshooting

Cloudflare Error 1015 Rate Limited: Causes and Backoff in Code

Cloudflare error 1015 means a site's rate limiting rule blocked you. How the rules count, the 429 status, and Python backoff that stops the retries.

By 6 min readPublished Updated

Cloudflare error 1015, “You are being rate limited”, means the site’s owner has a rate limiting rule and your client sent more matching requests than it allows in its counting period. Cloudflare answers a rate-limited request with HTTP 429 by default (the owner can choose any code from 400 to 499), and keeps doing so for the rule’s duration, which ranges from 10 seconds to one day depending on the owner’s plan and settings. The fix is on your side and in your code: send fewer requests, back off when you see 429 or 1015, and never retry in a tight loop, which Cloudflare warns “may extend the block.”

Only automate sites you are allowed to: your own, a client’s, or one whose terms permit it. See responsible captcha automation.

What Cloudflare’s docs say about error 1015

The error page (checked 1 October 2026) explains that “The website you are trying to visit has received too many requests and has temporarily blocked you from accessing it”, and names rate limiting rules as the cause. Its advice to visitors: “Wait for a period of time”, and “Do not repeatedly try to access the website within a short period of time, as this may extend the block.” It also tells visitors to contact the site owner, since the owner sets the rule. Its advice to owners is to review their thresholds, and, if a rule blocks within a very short period such as one second, to try increasing the period to 10 seconds.

How a rate limiting rule counts

A rate limiting rule matches requests with an expression, like any other WAF rule, then counts them. Its parameters, as Cloudflare documents them:

  • Characteristics: what makes requests count as coming from the same client. IP address on every plan; more options, such as headers, cookie, ASN, country, path or JA3/JA4 fingerprint, with Enterprise’s Advanced Rate Limiting.
  • Period and requests per period: the rate that triggers the rule.
  • Duration: how long the action applies once triggered.
  • Behavior: “Perform action during the selected duration” applies the rule’s action to every request received during the duration; “Throttle requests over the maximum configured rate”, an Enterprise add-on, acts only on the requests over the limit and lets the others through.

What each plan allows (checked 1 October 2026):

Plan Rules Counting period Duration (mitigation timeout) Characteristics
Free 1 10 s 10 s IP
Pro 2 Up to 1 minute Up to 1 hour IP
Business 5 Up to 10 minutes Up to 1 day IP, IP with NAT support
Enterprise 100 Up to 65,535 s Up to 1 day IP, IP with NAT support; with Advanced Rate Limiting also query, host, headers, cookie, ASN, country, path, JA3/JA4, custom

Two details matter for a client. First, Cloudflare says “Rate limiting rules are not designed to allow a precise number of requests to reach your origin server”: counters can update several seconds late, so don’t plan to run right at the limit. Second, a rate limiting rule’s action is not always a block. It can be block, a Non-Interactive, Managed or Interactive Challenge, or log, so a rate limit can also show up as a challenge page. See Cloudflare challenge types for those.

What your client receives

  • The status. “The default value is 429 (Too many requests)”, and an owner can enter any value “between 400 and 499”. On Pro plans and higher the owner can also set the response body and content type, so the page may not be Cloudflare’s.
  • The code. 1xxx errors “appear in the HTML body of the response”, so a default block page names 1015 in its body.
  • Retry-After. Cloudflare’s rate limiting docs don’t say that a Retry-After header is sent with a 1015 block (checked 1 October 2026). Its general 429 page says a server “may include a Retry-After header”. Use it when it is there; don’t depend on it.

Back off in code

This Python helper uses requests (pip install requests). It treats a 429, or a 4xx page that names 1015, as a rate limit; waits for Retry-After when the site sends one; otherwise doubles its wait from 10 seconds with random jitter; and gives up after six tries, or when asked to wait longer than ten minutes, instead of hammering.

import random
import time
from datetime import datetime, timezone
from email.utils import parsedate_to_datetime
import requests
def is_rate_limited(response):
if response.status_code == 429:
return True
# An owner can pick another 4xx code; Cloudflare puts the 1xxx code in the HTML body.
return 400 <= response.status_code < 500 and "1015" in response.text
def retry_after_seconds(response):
value = response.headers.get("Retry-After")
if not value:
return None
if value.isdigit():
return int(value)
try:
return max(0.0, (parsedate_to_datetime(value) - datetime.now(timezone.utc)).total_seconds())
except (TypeError, ValueError):
return None
def get_politely(session, url, tries=6, first_wait=10.0, longest_wait=600.0):
for attempt in range(tries):
response = session.get(url, timeout=30)
if not is_rate_limited(response):
return response
wait = retry_after_seconds(response)
if wait is None:
# Double the wait each time, with jitter so parallel workers don't retry together.
wait = random.uniform(0.5, 1.0) * min(longest_wait, first_wait * 2**attempt)
if attempt == tries - 1 or wait > longest_wait:
break
time.sleep(wait)
raise RuntimeError(f"still rate limited after {attempt + 1} tries: {url}")
session = requests.Session()
for url in ["https://shop.example.com/catalog?page=1", "https://shop.example.com/catalog?page=2"]:
page = get_politely(session, url)
print(url, page.status_code)
time.sleep(2) # a steady pace between pages, not a burst

The waits run 10, 20, 40, 80 and 160 seconds (each shortened by jitter), which covers the Free plan’s 10-second duration many times over and gives a longer block room to end. If six tries are not enough, the rule’s duration is longer than your job can wait: stop and look at your request rate rather than raising the retry count.

Stay under the limit

Backoff handles the error; pacing prevents it.

  • Send requests at a steady rate. Start slow and measure. Because counting is per period, a burst of parallel requests trips a rule that the same number spread out would not.
  • Cap concurrency across workers. Ten workers each pausing politely are still ten times the rate. Share one limit between them.
  • Fetch less. Cache what you already have, request only pages that changed, and skip assets you don’t need.
  • Treat a 1015 as a signal for the whole job, not for one URL. When one request is limited, the others from the same client are about to be.

Spread load over time, not over addresses. Rotating IP addresses so that each stays under a per-IP counter defeats a limit the owner set on purpose; if you need a higher rate, ask the owner, who can raise the threshold or exempt your traffic.

What a CAPTCHA solver does not change

A rate limit counts requests; no token or cookie resets the count. Cloudflare’s Challenge Passage documentation says “The Challenge Passage does not apply to rate limiting rules”, and a Cloudflare Turnstile token only proves a check on one form submission. ZeroCaptcha solves Cloudflare Turnstile, and has no feature for rate limits. If your client meets a challenge page rather than error 1015, the Cloudflare WAF and 5-second challenge solver page and the cf_clearance cookie explained cover that case. ZeroCaptcha’s own API has limits of its own, described in rate limits and concurrency.

For a hard refusal rather than a limit, see Cloudflare error 1020, and for how rate limiting rules sit among other rules, Cloudflare WAF rules explained.

Sources

The team that builds and runs the ZeroCaptcha API. Articles are drafted with AI tools, then checked against the API's code and the primary sources each one cites.

Questions

How long does Cloudflare error 1015 last?

As long as the site's rule says. The owner picks a duration, from 10 seconds up to one day depending on the plan, and Cloudflare warns that trying again repeatedly in a short time may extend the block.

What HTTP status comes with Cloudflare error 1015?

429 Too Many Requests by default. The owner of a rate limiting rule can set any status from 400 to 499 for its block response, and the 1015 code itself appears in the HTML body.

Does a cf_clearance cookie exempt me from Cloudflare rate limiting?

No. Cloudflare's Challenge Passage documentation says it 'does not apply to rate limiting rules', so a challenge you passed earlier does not raise the limit.

Read next

This article is part of the Cloudflare WAF and 5-second challenge solver hub. Every task is charged only when a token is ready.

Get an API key