# 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.

- Source: https://zerocaptcha.io/blog/cloudflare-error-1015
- Published: 2026-09-30
- Updated: 2026-10-01
- Author: ZeroCaptcha Engineering

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](https://zerocaptcha.io/guides/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](https://zerocaptcha.io/blog/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.

```python
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](https://zerocaptcha.io/cloudflare-challenge-solver) page and [the
cf_clearance cookie explained](https://zerocaptcha.io/guides/cf-clearance-cookie-explained) cover that case. ZeroCaptcha's
own API has limits of its own, described in [rate limits and
concurrency](https://zerocaptcha.io/guides/rate-limits-and-concurrency).

For a hard refusal rather than a limit, see [Cloudflare error 1020](https://zerocaptcha.io/blog/cloudflare-error-1020),
and for how rate limiting rules sit among other rules, [Cloudflare WAF rules
explained](https://zerocaptcha.io/blog/cloudflare-waf-rules-explained).

## Sources

- [Cloudflare: Error 1015](https://developers.cloudflare.com/support/troubleshooting/http-status-codes/cloudflare-1xxx-errors/error-1015/) (checked 1 October 2026)
- [Cloudflare: 1xxx errors](https://developers.cloudflare.com/support/troubleshooting/http-status-codes/cloudflare-1xxx-errors/) (checked 1 October 2026)
- [Cloudflare: Error 429](https://developers.cloudflare.com/support/troubleshooting/http-status-codes/4xx-client-error/error-429/) (checked 1 October 2026)
- [Cloudflare: Rate limiting rules](https://developers.cloudflare.com/waf/rate-limiting-rules/) (checked 1 October 2026)
- [Cloudflare: Rate limiting parameters](https://developers.cloudflare.com/waf/rate-limiting-rules/parameters/) (checked 1 October 2026)
- [Cloudflare: Create a rate limiting rule](https://developers.cloudflare.com/waf/rate-limiting-rules/create-zone-dashboard/), for custom responses on Pro plans and above (checked 1 October 2026)
- [Cloudflare: Challenge Passage](https://developers.cloudflare.com/cloudflare-challenges/challenge-types/challenge-pages/challenge-passage/) (checked 1 October 2026)

## 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.
