# 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=` (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 `). 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 `) 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.