Troubleshooting

Common reCAPTCHA v2 Solving Errors and Fixes

Most reCAPTCHA v2 failures fall into three buckets: request-stage mistakes (wrong parameters sent to the API), result-stage issues (polling problems or unsolvable tasks), and target-page rejections (the API returns a valid token but the page ignores it). The biggest culprits are almost always the same: wrong googlekey, incorrect pageurl, missing callback execution, or expired tokens.

This guide walks through every common failure pattern with the exact fix for each one. If you are new to reCAPTCHA v2 solving, read How to Solve reCAPTCHA v2 Using API first.


The four biggest reCAPTCHA v2 failure points

Before digging into individual error codes, check these first — they cover 80% of failures.

1. Wrong or missing googlekey

The googlekey (sitekey) comes from the data-sitekey attribute on the reCAPTCHA widget or the k parameter in the anchor URL. If this value is wrong, blank, or copied from a different page, the API rejects the task immediately with ERROR_GOOGLEKEY or ERROR_WRONG_GOOGLEKEY.

How to find the correct sitekey:

# Look for data-sitekey in the page HTML
# <div class="g-recaptcha" data-sitekey="6Le-wvkSVVABCPBMRTvw0Q4Muexq1bi0DJwx_mJ-"></div>

# Or find it in the anchor URL
# https://www.google.com/recaptcha/api2/anchor?k=6Le-wvkSVVABCPBMRTvw0Q4Muexq1bi0DJwx_mJ-

2. Wrong pageurl

The pageurl must be the exact URL where the reCAPTCHA widget loads. If the widget is inside an iframe hosted on a different domain, you need the iframe URL — not the parent page URL. Sending the wrong URL causes ERROR_PAGEURL or ERROR_BAD_TOKEN_OR_PAGEURL.

3. Callback not executed

Some pages use a JavaScript callback function instead of the hidden g-recaptcha-response field. If you inject the token into the hidden field but the page expects a callback, the form never submits. Check for data-callback on the widget or a callback property in grecaptcha.render().

4. Token expired or reused

reCAPTCHA tokens are valid for one use only and expire after about 2 minutes. If your automation takes too long between receiving the token and submitting the form, or if it reuses a token, the target page rejects it silently.


Request-stage errors (in.php)

These errors happen when you submit the CAPTCHA task to https://ocr.captchaai.com/in.php.

Error Code Cause Fix
ERROR_WRONG_USER_KEY API key format is invalid (not 32 characters) Check your API key at captchaai.com/api.php
ERROR_KEY_DOES_NOT_EXIST API key does not exist in the system Verify you copied the full key without extra spaces
ERROR_ZERO_BALANCE Account balance is zero Top up your account or check active thread count
ERROR_PAGEURL pageurl parameter is missing Add the full URL where the reCAPTCHA widget appears
ERROR_GOOGLEKEY googlekey is malformed or empty Extract the correct sitekey from the page
ERROR_WRONG_GOOGLEKEY googlekey parameter is missing entirely Add googlekey to your API request
ERROR_BAD_TOKEN_OR_PAGEURL The googlekey + pageurl pair is invalid Check if the widget is in an iframe; use the iframe URL
ERROR_BAD_PARAMETERS Required parameters are missing or malformed Review the API docs for required fields

Example: Correct request with error handling

import requests

def submit_recaptcha_v2(api_key, sitekey, page_url):
    response = requests.get("https://ocr.captchaai.com/in.php", params={
        "key": api_key,
        "method": "userrecaptcha",
        "googlekey": sitekey,
        "pageurl": page_url,
        "json": 1
    })

    data = response.json()

    if data.get("status") == 1:
        return data["request"]  # task ID

    error = data.get("request", "UNKNOWN_ERROR")

    if error == "ERROR_WRONG_USER_KEY":
        raise ValueError("API key format is invalid. Must be 32 characters.")
    elif error == "ERROR_ZERO_BALANCE":
        raise RuntimeError("Account balance is zero. Top up at captchaai.com")
    elif error == "ERROR_PAGEURL":
        raise ValueError("pageurl parameter is missing from request")
    elif error in ("ERROR_GOOGLEKEY", "ERROR_WRONG_GOOGLEKEY"):
        raise ValueError(f"Invalid sitekey. Verify the data-sitekey value on the page.")
    elif error == "ERROR_BAD_TOKEN_OR_PAGEURL":
        raise ValueError("Sitekey/pageurl mismatch. Check if widget is in an iframe.")
    else:
        raise RuntimeError(f"API error: {error}")

# Usage
task_id = submit_recaptcha_v2("YOUR_API_KEY", "6Le-wvkSAAAAAN...", "https://example.com/login")
print(f"Task submitted: {task_id}")
async function submitRecaptchaV2(apiKey, sitekey, pageUrl) {
  const params = new URLSearchParams({
    key: apiKey,
    method: "userrecaptcha",
    googlekey: sitekey,
    pageurl: pageUrl,
    json: 1,
  });

  const res = await fetch(`https://ocr.captchaai.com/in.php?${params}`);
  const data = await res.json();

  if (data.status === 1) return data.request;

  const error = data.request || "UNKNOWN_ERROR";
  const fixes = {
    ERROR_WRONG_USER_KEY: "API key format is invalid. Must be 32 characters.",
    ERROR_ZERO_BALANCE: "Account balance is zero. Top up at captchaai.com",
    ERROR_PAGEURL: "pageurl parameter is missing from request",
    ERROR_GOOGLEKEY: "Invalid sitekey. Check the data-sitekey attribute.",
    ERROR_BAD_TOKEN_OR_PAGEURL: "Sitekey/pageurl mismatch. Check iframe context.",
  };

  throw new Error(fixes[error] || `API error: ${error}`);
}

// Usage
const taskId = await submitRecaptchaV2("YOUR_API_KEY", "6Le-wvkSAAAAAN...", "https://example.com/login");
console.log(`Task submitted: ${taskId}`);

Result-stage errors (res.php)

These errors happen when polling https://ocr.captchaai.com/res.php for the result.

Error Code Cause Fix
CAPCHA_NOT_READY Solve is still in progress Wait 5 seconds and poll again. This is normal.
ERROR_CAPTCHA_UNSOLVABLE The CAPTCHA could not be solved Submit a new task with fresh parameters
ERROR_WRONG_ID_FORMAT Task ID format is invalid Verify the ID returned from in.php
ERROR_WRONG_CAPTCHA_ID Task ID does not exist Check that you saved the correct task ID
ERROR_EMPTY_ACTION action=get parameter is missing Add action=get to your polling request

Example: Polling with proper error handling

import time
import requests

def poll_result(api_key, task_id, timeout=120):
    start = time.time()

    while time.time() - start < timeout:
        time.sleep(5)

        response = requests.get("https://ocr.captchaai.com/res.php", params={
            "key": api_key,
            "action": "get",
            "id": task_id,
            "json": 1
        })

        data = response.json()

        if data.get("status") == 1:
            return data["request"]  # solved token

        error = data.get("request", "")

        if error == "CAPCHA_NOT_READY":
            continue  # normal — keep waiting
        elif error == "ERROR_CAPTCHA_UNSOLVABLE":
            raise RuntimeError("CAPTCHA unsolvable. Submit a new task with fresh params.")
        elif error in ("ERROR_WRONG_ID_FORMAT", "ERROR_WRONG_CAPTCHA_ID"):
            raise ValueError(f"Invalid task ID: {task_id}")
        else:
            raise RuntimeError(f"Polling error: {error}")

    raise TimeoutError(f"Solve timed out after {timeout}s")

# Usage
token = poll_result("YOUR_API_KEY", task_id)
print(f"Token: {token[:50]}...")
async function pollResult(apiKey, taskId, timeout = 120000) {
  const start = Date.now();

  while (Date.now() - start < timeout) {
    await new Promise((r) => setTimeout(r, 5000));

    const params = new URLSearchParams({
      key: apiKey,
      action: "get",
      id: taskId,
      json: 1,
    });

    const res = await fetch(`https://ocr.captchaai.com/res.php?${params}`);
    const data = await res.json();

    if (data.status === 1) return data.request;

    if (data.request === "CAPCHA_NOT_READY") continue;
    if (data.request === "ERROR_CAPTCHA_UNSOLVABLE")
      throw new Error("Unsolvable. Submit a new task.");
    throw new Error(`Polling error: ${data.request}`);
  }

  throw new Error(`Solve timed out after ${timeout / 1000}s`);
}

Target-page rejections

The API returned a valid token but the target site still rejects it. These are the hardest failures to debug because the API thinks everything worked.

Token injected into the wrong field

Some pages look for the token in the g-recaptcha-response textarea. Others use grecaptcha.getResponse(). Others expect a callback. If you pick the wrong injection method, the form submission fails silently.

Fix: Inspect the page to determine the expected path:

# Method 1: Hidden field injection
driver.execute_script(
    'document.getElementById("g-recaptcha-response").innerHTML = arguments[0];',
    token
)

# Method 2: Callback execution (check data-callback attribute)
driver.execute_script(f'onCaptchaSuccess("{token}");')

# Method 3: Direct form field + submit
driver.execute_script(
    'document.querySelector("[name=g-recaptcha-response]").value = arguments[0];',
    token
)
driver.find_element("css selector", "form").submit()

Callback not triggered

If the widget has data-callback="onSuccess" or uses grecaptcha.render() with a callback property, filling the hidden field alone does nothing. You must call the callback function directly.

Fix: Find and call the callback:

// In browser console or Puppeteer/Playwright
// Check for data-callback
const widget = document.querySelector('.g-recaptcha');
const callbackName = widget?.getAttribute('data-callback');
if (callbackName && window[callbackName]) {
  window[callbackName](token);
}

Token expired

If more than ~2 minutes pass between receiving the token and submitting the form, Google rejects it. This is common in slow automation pipelines.

Fix: Submit the form immediately after receiving the token. If your pipeline is slow, request the solve closer to the submission step rather than at the start.

Widget is in an iframe

If the reCAPTCHA loads inside an iframe from a different domain, you must use the iframe source URL as pageurl, not the parent page URL. The ERROR_BAD_TOKEN_OR_PAGEURL error usually signals this problem.

Fix: Inspect the page, find the iframe containing the reCAPTCHA, and use that iframe's src URL as your pageurl.


Quick diagnosis checklist

Symptom First thing to check
ERROR_GOOGLEKEY or ERROR_WRONG_GOOGLEKEY Is the sitekey copied correctly from data-sitekey?
ERROR_PAGEURL Did you include the full page URL?
ERROR_BAD_TOKEN_OR_PAGEURL Is the widget inside an iframe? Use the iframe URL.
CAPCHA_NOT_READY for over 3 minutes Normal for hard challenges. Increase timeout to 180s.
ERROR_CAPTCHA_UNSOLVABLE Submit a new task. If repeated, verify sitekey + pageurl.
Token works but page does nothing Check for data-callback. Call the callback function.
Token returns but form still fails Token may be expired (>2 min). Submit faster.
Intermittent failures Add retry logic with fresh task IDs.

FAQ

Why does reCAPTCHA v2 fail even when the request looks correct?

The three most common causes are: (1) the pageurl does not match the actual widget context — especially when the widget is inside an iframe, (2) the page expects a callback function but you only filled the hidden field, or (3) the token expired before you submitted the form.

What is the most common reCAPTCHA v2 solving mistake?

Using the wrong googlekey or wrong pageurl. This is especially common when the reCAPTCHA widget loads in an iframe on a different domain or subdomain — the sitekey and URL must match the iframe context, not the parent page.

What does CAPCHA_NOT_READY mean?

It means the CAPTCHA is still being solved. This is not an error. Wait 5 seconds and poll res.php again. Typical reCAPTCHA v2 solve times are 15–60 seconds.

What should I do if the API returns a token but the page still rejects it?

Check three things in order: (1) Does the page use a callback? Look for data-callback on the widget. (2) Is your pageurl correct — especially if the widget is in an iframe? (3) Did more than 2 minutes pass between receiving and using the token?

How do I handle ERROR_CAPTCHA_UNSOLVABLE?

Submit a new task with fresh parameters. Do not retry the same task ID. If this error happens repeatedly, verify your sitekey and pageurl match the actual page and that the CAPTCHA type is standard reCAPTCHA v2 (not Enterprise — which requires different parameters).


Fix your reCAPTCHA v2 workflow

  1. Verify your inputs — extract googlekey from data-sitekey and use the exact page URL (check for iframes)
  2. Check the injection method — determine whether the page expects hidden field, callback, or both
  3. Submit immediately — use the token within 2 minutes of receiving it
  4. Add error handling — use the code examples above to catch and handle every error type

Start solving reCAPTCHA v2 with the CaptchaAI solver. Get your API key from captchaai.com/api.php.


Discussions (0)

No comments yet.