Files
autoreg-skills-max/skills/ai-provider-autoreg/references/captcha-solver-infra.md

4.0 KiB

Captcha-solver infra: sidecar contention + proxy-egress alignment

Cross-farm rules for ANY registration wave that solves Turnstile/reCAPTCHA through a local browser solver (cs_sidecar server.py, or conol's chrome_cdp) while rotating proxies. These bite when running several farms at once or behind proxy rotation.

1. One solver instance per concurrent wave (else HTTP 408)

The local captcha sidecar enforces a server-side per-solve deadline (~60s). Two concurrent farm waves pointed at the SAME port (e.g. miarouter + ablit both on :8877) queue their solves past the deadline and get HTTP 408 Request Timeout; the farm then retries forever and makes zero progress.

  • Fix: start a SECOND instance on another port via the PORT env var (PORT=8879 python -u server.py), and repoint one farm's solver URL (SIDE = "http://127.0.0.1:8879/solve"). The sidecar reads its port from os.getenv("PORT", "8877"), so no code edit is needed to spawn an extra instance.
  • Rule: N concurrent captcha-consuming waves → N sidecar instances, one port each. Never share a single solver across parallel farms.
  • A contended sidecar still answers GET /health instantly — health is NOT proof of capacity. Verify with a real POST /solve round-trip before declaring it working.

2. Captcha-browser egress IP MUST equal the registration egress IP

reCAPTCHA v3 / Turnstile are score-based and IP-bound: the server-side siteverify compares the IP that SOLVED the captcha against the IP that SUBMITS the register token. If the register HTTP goes through a proxy (HTTPS_PROXY env → requests honors it) but the captcha browser solves from the home IP, the token is rejected with CAPTCHA_VERIFICATION_FAILED ("Human verification failed") even though the solve itself returned a valid-looking token. Symptom: solve succeeds, register 403s on captcha.

  • Fix: route the captcha browser through the SAME proxy as the register calls. For a Chrome-CDP solver, patch the launcher to append --proxy-server=<proxy> (read from an env var, e.g. CONOL_CHROME_PROXY), and KILL + RELAUNCH the captcha Chrome before each proxy rotation — the browser is launched once and reused, so a stale proxy persists across every subsequent solve otherwise.
  • Kill the captcha Chrome by the PID LISTENING on its CDP port (e.g. netstat -ano | grep :9228 → taskkill /F /T /PID <pid>). That Chrome is the dedicated solver instance (own --user-data-dir), NOT the user's main browser — never kill by image name (taskkill /IM chrome.exe would take down the user's browser).
  • Caveat: free datacenter proxies usually cannot even load a Cloudflare-fronted captcha page (browser hangs, solve fails before a token exists). Egress alignment only pays off with residential/clean proxies that can actually render the captcha site. If every proxy in a free pool fails the captcha load, the bottleneck is proxy quality, not the alignment wiring.

3. Key-pool drain: never trust pool order

Farm scripts that read the first key of a captcha-key pool file (keys[0]) fail with ERROR_ZERO_BALANCE the moment that key drains — even when funded backups sit next to it in the same file. A mid-wave drain looks like a captcha outage, not a billing problem.

  • Before a wave, check EVERY pool key: POST https://api.2captcha.com/res.php with {key, action:getbalance} — balance checks must be POST; a GET returns a misleading ERROR_WRONG_USER_KEY.
  • Scripts should iterate the pool: on ERROR_ZERO_BALANCE, move to the next key with a positive balance instead of aborting the run.
  • Turnstile solves are cheap per unit but long waves add up; re-check balances before each wave, not once per day.

4. Gateway interruption kills background waves

A Hermes gateway restart/interruption terminates background farm processes. After any interruption, do NOT trust the in-memory process list — check each wave's log mtime (stat -c %y <log>) against date; a stale mtime means the wave died and must be relaunched. Resume-able farms (state file per wave) pick up where they left off; others restart from scratch.