CAPTCHA solver APIs (CaptchaAI, 2Captcha, and compatible services) return standardized error codes. Most errors are straightforward to fix once you know what they mean. This guide covers the complete error code list and includes fixes for each.
For a full troubleshooting overview, see the CAPTCHA Solver Troubleshooting Guide.
Reading the API Response
Both the submit endpoint (/in.php) and poll endpoint (/res.php) return JSON with a status field:
// Success
{"status": 1, "request": "TASK_ID_OR_TOKEN"}
// Error
{"status": 0, "request": "ERROR_CODE_HERE"}
Always check status before using request. Never assume the response is a token.
r = requests.post("https://ocr.captchaai.com/in.php", data=payload, timeout=30)
data = r.json()
if data.get("status") != 1:
raise RuntimeError(f"API error: {data['request']}")
task_id = data["request"]
Submit Endpoint Errors (/in.php)
ERROR_WRONG_USER_KEY
Cause: The key parameter is missing, blank, or malformed.
Fix: Verify your API key is a non-empty string with no whitespace. Print the key length — it should typically be 32 characters.
print(f"Key length: {len(api_key)}, Key: {api_key[:8]}...") # Print first 8 chars safely
ERROR_KEY_DOES_NOT_EXIST
Cause: The API key is well-formed but not registered on this solver. Fix: Confirm you're using the key from the correct service. CaptchaAI keys don't work on 2Captcha's API and vice versa — unless you use the correct base URL for each.
ERROR_ZERO_BALANCE
Cause: Your account has no credits remaining. Fix: Top up your balance. Use the balance check endpoint to add monitoring:
r = requests.get("https://ocr.captchaai.com/res.php", params={
"key": api_key, "action": "getbalance", "json": 1
})
balance = r.json().get("request", "0")
print(f"Balance: ${balance}")
ERROR_PAGEURL
Cause: The pageurl parameter is missing or malformed.
Fix: Pass the full page URL including scheme: https://example.com/login. Do not pass relative paths.
ERROR_NO_SLOT_AVAILABLE
Cause: The solver's queue is full — no workers available. Fix: Retry with exponential backoff. Peak hours (US/EU mornings) have higher queue depth. Consider switching solvers during peak periods.
ERROR_WRONG_CAPTCHA_ID
Cause: The method parameter doesn't match the CAPTCHA type on the page.
Fix: Use the correct method for the CAPTCHA type:
- userrecaptcha for reCAPTCHA v2/v3
- hcaptcha for hCaptcha
- turnstile for Cloudflare Turnstile
- geetest for GeeTest v3, geetest4 for v4
- funcaptcha for FunCaptcha / Arkose Labs
ERROR_WRONG_GOOGLEKEY
Cause: The site key (googlekey or sitekey) is invalid or in the wrong format.
Fix: Re-extract the site key from the live page. reCAPTCHA site keys are ~40 alphanumeric characters. hCaptcha site keys are UUID format.
IP_BANNED
Cause: Requests from your IP are blocked by the solver. Fix: Contact solver support. Typically happens after automated abuse patterns or excessive error rates.
Poll Endpoint Responses (/res.php)
CAPCHA_NOT_READY / CAPTCHA_NOT_READY
What it means: Task is still in progress — not an error.
Action: Continue polling. Check both spellings — both appear in the wild (the typo CAPCHA_NOT_READY exists in some implementations).
not_ready_states = {"CAPCHA_NOT_READY", "CAPTCHA_NOT_READY"}
if data.get("request") in not_ready_states:
time.sleep(5)
continue
ERROR_CAPTCHA_UNSOLVABLE
Cause: The solver attempted the challenge and failed. Several sub-causes:
- Image is too degraded to solve
- Site key is invalid (challenge never loads for the worker)
- min_score requested is too high (v3/Enterprise)
- Worker received an expired challenge parameter (GeeTest v3)
Fix: Retry with a fresh task. If persistent, check:
1. The site key is valid and the page loads correctly
2. For v3, reduce min_score or remove it
3. For GeeTest v3, fetch a fresh challenge before each task
ERROR_WRONG_ID_FORMAT
Cause: The task ID passed to the poll endpoint is malformed. Fix: Use the exact string returned by the submit endpoint. Don't parse or truncate it.
ERROR_WRONG_CAPTCHA_ID
Cause (at poll): Task ID doesn't exist. Fix: The task may have expired (older solvers expire tasks after 10 minutes). Re-submit and poll within the valid window.
ERROR_BANNED
Cause: Account banned. Fix: Contact solver support.
Full Error Reference Table
| Error Code | Endpoint | Cause | Fix |
|---|---|---|---|
ERROR_WRONG_USER_KEY |
Submit | API key malformed | Verify key format |
ERROR_KEY_DOES_NOT_EXIST |
Submit | Key not found | Use correct solver's key |
ERROR_ZERO_BALANCE |
Submit | No credits | Top up balance |
ERROR_PAGEURL |
Submit | Missing or invalid URL | Pass full https:// URL |
ERROR_NO_SLOT_AVAILABLE |
Submit | Queue full | Retry with backoff |
ERROR_WRONG_CAPTCHA_ID |
Submit | Wrong method | Match method to CAPTCHA type |
ERROR_WRONG_GOOGLEKEY |
Submit | Invalid site key | Re-extract from live page |
IP_BANNED |
Submit | IP blocked | Contact support |
CAPTCHA_NOT_READY |
Poll | Still in progress | Keep polling |
ERROR_CAPTCHA_UNSOLVABLE |
Poll | Solve failed | Retry; check site key |
ERROR_WRONG_ID_FORMAT |
Poll | Malformed task ID | Use exact string from submit |
ERROR_WRONG_CAPTCHA_ID |
Poll | Task expired/not found | Re-submit task |
ERROR_BANNED |
Poll | Account banned | Contact support |
Error Handling Pattern
RETRYABLE_ERRORS = {"ERROR_NO_SLOT_AVAILABLE"}
FATAL_ERRORS = {
"ERROR_WRONG_USER_KEY", "ERROR_KEY_DOES_NOT_EXIST",
"ERROR_ZERO_BALANCE", "IP_BANNED", "ERROR_BANNED",
}
def submit_with_error_handling(payload: dict, api_key: str) -> str:
for attempt in range(5):
r = requests.post("https://ocr.captchaai.com/in.php", data=payload, timeout=30)
data = r.json()
if data.get("status") == 1:
return data["request"]
error = data.get("request", "UNKNOWN")
if error in FATAL_ERRORS:
raise RuntimeError(f"Fatal API error (will not retry): {error}")
if error in RETRYABLE_ERRORS:
time.sleep(10 * (attempt + 1))
continue
raise RuntimeError(f"Submission error: {error}")
raise RuntimeError("Max submit retries reached")
Related Guides
- CAPTCHA Solver Troubleshooting Guide — full overview
- CAPTCHA Solver Timeout Errors — poll timeout fixes
- CAPTCHA Solver Low Success Rate — tokens returned but rejected
Production Readiness Notes
Use CAPTCHA Solver API Errors — Error Codes and Fixes as a decision and implementation aid, not just as a one-time reference. The practical test for captcha solver api errors is whether the same approach behaves reliably when traffic is messy: rotating sessions, expired tokens, changing widget parameters, intermittent solver delays, and target pages that refresh without warning. For Developer debugging CAPTCHA API integration errors, the safest rollout is to start with a narrow fixture, record every submitted task, and compare the solver response with the browser state that finally submits the form. That makes failures explainable instead of mysterious, especially when a target alternates between visible challenges, invisible checks, and server-side verification.
Evaluation Criteria
A developer guide should become a reusable integration module with typed configuration, bounded polling, structured errors, and a single place for API credentials. For troubleshooting work, the most useful scorecard combines technical acceptance with operational cost. A low nominal price is not enough if retries double the real cost per accepted token, and a fast median solve time is not enough if p95 latency stalls the queue. Track these criteria before you standardize the workflow:
- The challenge subtype, sitekey, action, rqdata, blob, captchaId, or page URL used for each task.
- Median and p95 solve time, separated by provider and target domain.
- Accepted-token rate on the target page, not just successful API responses.
- Retry count, timeout count, zero-balance incidents, and invalid-parameter errors.
- The exact browser, proxy region, and user-agent that submitted the solved token.
Rollout Checklist
Before this guidance moves into a production job, build a small acceptance suite around the pages that matter most. Run it with a fixed browser profile, then repeat with the proxy and concurrency settings you expect in production. Keep the first release conservative: bounded polling, clear timeout handling, and a fallback path when the solver cannot return a usable answer. For troubleshooting, preserve the original request payload, solver response, page URL, sitekey, proxy, and browser fingerprint before changing multiple variables. That checklist keeps the article useful after the first copy-paste, because the integration is judged by end-to-end completion rather than by whether a code sample returned a string.
Monitoring Signals
Healthy CAPTCHA automation is observable. Log the task id, provider, challenge type, target host, queue time, solve time, final submit status, and normalized error code for every attempt. Review those logs in daily batches at first, then move to alerts once the baseline is stable. Sudden drops usually come from target-side changes: a new sitekey, a changed action name, a stricter hostname check, an added managed challenge, or a proxy pool that no longer matches the expected geography. When you can see those shifts quickly, provider switching becomes a controlled decision instead of a late-night rewrite.
Maintenance Cadence
Revisit the setup whenever the target UI changes, when the solver provider changes task names or pricing, or when benchmark data shows a sustained latency or solve-rate shift. Keep one known-good fixture for each CAPTCHA subtype and rerun it after dependency upgrades, browser updates, and proxy changes. If the article is used for vendor selection, repeat the same fixture across at least two providers before renewing a balance or migrating the whole pipeline. That habit keeps captcha solver api errors work aligned with the real target behavior rather than with stale assumptions.