Если reCAPTCHA v2 отклоняет запрос или токен, в 80% случаев причина одна из четырёх: неверный googlekey, неточный pageurl, необработанный callback или просроченный токен. Остальные ошибки делятся всего на три группы — сбои на этапе отправки задачи в API, сбои на этапе опроса результата и отказ уже на стороне целевой страницы, когда токен формально валиден, но форма всё равно не уходит.
Ниже — разбор каждой группы по кодам ошибок и точный порядок диагностики. Если вы только настраиваете интеграцию, сначала прочитайте руководство «Как решить reCAPTCHA v2 через API» — там описан базовый цикл запроса и опроса, на который опирается этот материал.
Сверьтесь с таблицей ниже — она закрывает 80% обращений. Не нашли код ошибки — переходите к разделу
in.php/res.php.
С чего начать: четыре главные причины сбоев
Прежде чем разбирать отдельные коды ошибок, сверьтесь с таблицей ниже.
| Причина | Типичный код ошибки | Быстрая проверка |
|---|---|---|
googlekey указан неверно или отсутствует |
ERROR_GOOGLEKEY, ERROR_WRONG_GOOGLEKEY |
Значение совпадает с data-sitekey на текущей странице? |
pageurl не совпадает с реальным адресом виджета |
ERROR_PAGEURL, ERROR_BAD_TOKEN_OR_PAGEURL |
Виджет не находится в iframe стороннего домена? |
| Не выполняется обратный вызов (callback) | форма не отправляется без явной ошибки API | Есть ли на виджете data-callback или свойство callback? |
| Токен истёк или использован повторно | целевая страница молча отклоняет токен | Между получением токена и отправкой формы прошло меньше 2 минут? |
Как найти правильный site key
googlekey (он же site key) берётся из атрибута data-sitekey виджета reCAPTCHA либо из параметра k в URL якоря (anchor URL). Если значение неверно, пусто или скопировано с другой страницы, API сразу отклоняет задачу с кодом ERROR_GOOGLEKEY или ERROR_WRONG_GOOGLEKEY.
# 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-
Пример из практики: staging-логин за iframe
Команда, тестирующая форму записи через сторонний портал (например, поток авторизации визового или консульского сервиса в staging), почти всегда получает ERROR_BAD_TOKEN_OR_PAGEURL. Причина стандартная: виджет reCAPTCHA v2 отрисован внутри iframe партнёрского домена, а в запросе указан URL родительской страницы вместо адреса самого iframe.
Если проверки разворачиваются одновременно из нескольких регионов — например, из европейских дата-центров и из площадок в Казахстане, как часто устроена инфраструктура у русскоязычных команд, — параллельные повторные запросы легко начинают выстраиваться в очередь.
Держите запас по потокам под пиковую нагрузку: например, ADVANCE ($90/мес, 50 потоков) вместо стартового BASIC ($15/мес, 5 потоков).
В логи ошибок стоит писать pageurl, googlekey и код ошибки, но не значения самой формы — если тестовый сценарий касается персональных данных, это релевантно и с точки зрения 152-ФЗ «О персональных данных» для читателей из РФ, и с точки зрения обычной GDPR-гигиены для остальной аудитории.
Ошибки этапа запроса: коды in.php
Эти ошибки возникают при отправке задачи на https://ocr.captchaai.com/in.php.
Ошибки ключа и баланса
| Код ошибки | Причина | Как исправить |
|---|---|---|
ERROR_WRONG_USER_KEY |
Неверный формат ключа API (не 32 символа) | Проверьте ключ на captchaai.com/api.php |
ERROR_KEY_DOES_NOT_EXIST |
Такого ключа API нет в системе | Убедитесь, что скопировали ключ полностью, без лишних пробелов |
ERROR_ZERO_BALANCE |
Баланс аккаунта равен нулю | Пополните счёт или проверьте количество активных потоков |
Ошибки параметров запроса
| Код ошибки | Причина | Как исправить |
|---|---|---|
ERROR_PAGEURL |
Параметр pageurl отсутствует |
Добавьте полный URL страницы с виджетом reCAPTCHA |
ERROR_GOOGLEKEY |
googlekey имеет неверный формат или пуст |
Извлеките корректный site key со страницы |
ERROR_WRONG_GOOGLEKEY |
Параметр googlekey вообще отсутствует в запросе |
Добавьте googlekey в тело запроса |
ERROR_BAD_TOKEN_OR_PAGEURL |
Пара googlekey + pageurl не совпадает |
Проверьте, не в iframe ли виджет; используйте адрес iframe |
ERROR_BAD_PARAMETERS |
Обязательные параметры отсутствуют или заданы неверно | Сверьтесь с документацией по API — там перечислены обязательные поля |
Пример: корректный запрос с обработкой ошибок
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://staging.example.com/qa-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://staging.example.com/qa-login");
console.log(`Task submitted: ${taskId}`);
Ошибки опроса результата: коды res.php
Эти ошибки возникают при опросе https://ocr.captchaai.com/res.php в ожидании результата.
Нормальное ожидание и неразрешимые задачи
| Код ошибки | Причина | Как исправить |
|---|---|---|
CAPCHA_NOT_READY |
Решение ещё не готово | Подождите 5 секунд и опросите повторно — это нормальное состояние |
ERROR_CAPTCHA_UNSOLVABLE |
CAPTCHA не удалось решить | Отправьте новую задачу со свежими параметрами |
Ошибки идентификатора задачи
| Код ошибки | Причина | Как исправить |
|---|---|---|
ERROR_WRONG_ID_FORMAT |
Неверный формат ID задачи | Проверьте ID, который вернул in.php |
ERROR_WRONG_CAPTCHA_ID |
Такого ID задачи не существует | Убедитесь, что сохранили правильный ID |
ERROR_EMPTY_ACTION |
Отсутствует параметр action=get |
Добавьте action=get в запрос опроса |
Пример: опрос с корректной обработкой ошибок
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`);
}
Когда токен есть, а сайт всё равно его отклоняет
API вернул валидный токен, но целевой сайт его не принимает. Это самая неприятная категория ошибок: с точки зрения API всё прошло успешно, значит искать проблему нужно в самой странице.
Токен подставлен не в то поле
Одни страницы ищут токен в textarea g-recaptcha-response. Другие читают его через grecaptcha.getResponse(). Третьи ждут callback. Если выбран не тот способ внедрения, отправка формы падает без явной ошибки.
Исправление. Определите, какой путь ожидает страница:
# 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 не запускается
Если у виджета есть data-callback="onSuccess" или он инициализирован через grecaptcha.render() со свойством callback, одного заполнения скрытого поля недостаточно — callback нужно вызвать явно.
Исправление. Найдите и вызовите 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);
}
Токен успел истечь
Если между получением токена и отправкой формы прошло больше ~2 минут, Google его отклонит — типичная проблема медленных конвейеров автоматизации. Исправление: отправляйте форму сразу после получения токена; если конвейер работает медленно, запрашивайте решение ближе к шагу отправки, а не в самом начале сценария.
Виджет находится в iframe
Если reCAPTCHA рендерится внутри iframe с другого домена, в качестве pageurl нужен исходный URL этого iframe, а не адрес родительской страницы — ошибка ERROR_BAD_TOKEN_OR_PAGEURL почти всегда сигнализирует именно об этом. Исправление: найдите iframe с reCAPTCHA на странице и используйте его атрибут src в качестве pageurl.
Чек-лист быстрой диагностики
Держите под рукой при разборе тикета — начните с совпадающего симптома.
ERROR_GOOGLEKEYилиERROR_WRONG_GOOGLEKEY— правильно ли скопирован site key изdata-sitekey?ERROR_PAGEURL— передан ли полный URL страницы?ERROR_BAD_TOKEN_OR_PAGEURL— не находится ли виджет в iframe? Используйте URL iframe.CAPCHA_NOT_READYдольше 3 минут — нормально для сложных заданий, увеличьте таймаут до 180 с.ERROR_CAPTCHA_UNSOLVABLE— отправьте новую задачу; если повторяется, перепроверьте sitekey и pageurl.- Токен есть, но страница не реагирует — проверьте
data-callbackи вызовите функцию обратного вызова. - Токен получен, но форма всё равно не уходит — возможно, токен истёк (>2 минут), отправляйте быстрее.
- Сбои возникают периодически — добавьте повтор с новыми ID задач вместо переиспользования старых.
Частые вопросы об ошибках reCAPTCHA v2
Чем ошибки in.php отличаются от ошибок res.php?
Разница в том, на каком этапе запроса они возникают:
- Коды
in.php(ERROR_GOOGLEKEY,ERROR_PAGEURL,ERROR_WRONG_USER_KEYи другие) относятся к моменту отправки задачи — обычно это неверные параметры запроса. - Коды
res.php(CAPCHA_NOT_READY,ERROR_CAPTCHA_UNSOLVABLE,ERROR_WRONG_ID_FORMAT) относятся к опросу уже принятой задачи.
Если ошибка пришла сразу — смотрите in.php; если после нескольких секунд опроса — res.php.
Как быстро понять, что дело в iframe, а не в самом sitekey?
Откройте DevTools, найдите виджет reCAPTCHA и проверьте, лежит ли он внутри <iframe> с доменом, отличным от адресной строки браузера. Если да — pageurl должен быть равен src этого iframe, а не URL из адресной строки. Именно это чаще всего стоит за ERROR_BAD_TOKEN_OR_PAGEURL, даже когда googlekey скопирован верно.
Сколько живёт токен reCAPTCHA v2 и что будет, если не уложиться в это время?
Токен одноразовый и действует около 2 минут с момента выдачи. Если форма отправляется позже или тот же токен переиспользуется повторно, целевая страница отклоняет его без явного кода ошибки на стороне CaptchaAI — с точки зрения API задача была решена успешно.
Нужно ли что-то менять для reCAPTCHA v2 Enterprise?
Да — Enterprise-версия принимает дополнительные параметры и по-другому ведёт себя при повторных ошибках ERROR_CAPTCHA_UNSOLVABLE. Если ошибка стабильно повторяется на одной и той же странице, проверьте:
- Не подключает ли страница
enterprise.jsвместо стандартногоapi.js— это первый признак Enterprise-версии. - Не передаёт ли интеграция
action/expected_action— эти параметры специфичны для reCAPTCHA v2 Enterprise.
Что означает CAPCHA_NOT_READY и когда пора увеличивать таймаут?
Это не ошибка, а нормальное состояние: решение ещё выполняется. Подождите 5 секунд и опросите res.php снова. Типичное время решения reCAPTCHA v2 — 15–60 секунд; если задача сложная и превышает 3 минуты, увеличьте таймаут опроса до 180 секунд, прежде чем считать это сбоем.
Как закрепить рабочий процесс reCAPTCHA v2
Закройте эти типичные причины повторных сбоев прямо в интеграции:
- Не хардкодьте
pageurl— берите его динамически, если адрес тестовой страницы может измениться. - Не переиспользуйте
task_idпосле того, как он уже вернул токен. - Не запрашивайте решение в начале сценария, если до отправки формы ещё далеко.
- Проверьте входные данные — извлеките
googlekeyизdata-sitekeyи используйте точный URL страницы, проверив наличие iframe. - Определите способ внедрения — выясните, ждёт ли страница скрытое поле, callback или оба варианта сразу.
- Отправляйте немедленно — используйте токен в течение 2 минут после получения.
- Добавьте обработку ошибок — возьмите примеры кода выше, чтобы перехватывать и корректно обрабатывать каждый тип сбоя.
Начните решать reCAPTCHA v2 через решатель CaptchaAI. API-ключ можно получить на captchaai.com/api.php.
Связанные руководства
- Как решить reCAPTCHA v2 через API — полное пошаговое руководство
- Как решить callback reCAPTCHA v2 через API — отдельный разбор обратного вызова
- Как устроена задача reCAPTCHA grid — механика grid-заданий
- Справочник кодов ошибок CaptchaAI — полный список кодов ошибок