searxng/searxng · error · SearxEngineCaptchaException

Cloudflare CAPTCHA

Error message

Cloudflare CAPTCHA

What it means

After an HTTP >=400 response, if the Server header starts with 'cloudflare' and the body matches a Cloudflare challenge/CAPTCHA page, SearxEngineCaptchaException is raised and the engine is suspended (default 2 weeks per suspended_times.cf_SearxEngineCaptcha).

Source

Thrown at searx/network/raise_for_httperror.py:38

            and 'orchestrate/jsch/v1' in resp.text
            and 'window._cf_chl_enter(' in resp.text
        ):
            return True
    if resp.status_code == 403 and '__cf_chl_captcha_tk__=' in resp.text:
        return True
    return False


def is_cloudflare_firewall(resp: "SXNG_Response"):
    return resp.status_code == 403 and '<span class="cf-error-code">1020</span>' in resp.text


def raise_for_cloudflare_captcha(resp: "SXNG_Response"):
    if resp.headers.get('Server', '').startswith('cloudflare'):
        if is_cloudflare_challenge(resp):
            # https://support.cloudflare.com/hc/en-us/articles/200170136-Understanding-Cloudflare-Challenge-Passage-Captcha-
            # suspend for 2 weeks
            raise SearxEngineCaptchaException(
                message='Cloudflare CAPTCHA', suspended_time=get_setting('search.suspended_times.cf_SearxEngineCaptcha')
            )

        if is_cloudflare_firewall(resp):
            raise SearxEngineAccessDeniedException(
                message='Cloudflare Firewall',
                suspended_time=get_setting('search.suspended_times.cf_SearxEngineAccessDenied'),
            )


def raise_for_recaptcha(resp: "SXNG_Response"):
    if resp.status_code == 503 and '"https://www.google.com/recaptcha/' in resp.text:
        raise SearxEngineCaptchaException(
            message='ReCAPTCHA', suspended_time=get_setting('search.suspended_times.recaptcha_SearxEngineCaptcha')
        )


def raise_for_captcha(resp: "SXNG_Response"):

View on GitHub (pinned to 9fea41204f)

Solutions

  1. Wait out the suspension or restart to clear it
  2. Route that engine's traffic through a residential proxy (outgoing.proxies / per-engine networks)
  3. Reduce request rate for the affected engine
Defensive patterns

Strategy: retry

Type guard

def is_cloudflare_challenge_resp(resp) -> bool:
    return resp.headers.get('Server', '').startswith('cloudflare') and is_cloudflare_challenge(resp)

Try / catch

try:
    search(...)
except SearxEngineCaptchaException as e:
    suspend_and_use_backup_engine(e.suspended_time)

Prevention

When it happens

Trigger: An engine behind Cloudflare returns a challenge page (403/503 with cf challenge markers) during search.

Common situations: Engines like certain scrape-based ones getting challenged due to datacenter IPs or rate limits; no impact from user config.

Related errors


AI-assisted analysis of searxng/searxng@9fea41204f (2026-08-27). Data as JSON: /api/errors/8bccce28d1199c25. Report an issue: GitHub.