Casi todos los fallos al resolver un Cloudflare Challenge se explican con tres variables: el proxy, la IP desde la que usas la cookie y el User-Agent. Si no coinciden entre la resolución y las solicitudes posteriores, el sitio te devuelve el desafío aunque la API haya respondido bien. Aquí tienes cada código de error y qué cambiar para que deje de aparecer.
Empieza por este checklist
- ✅ ¿La protección es Cloudflare Challenge y no Turnstile o reCAPTCHA?
- ✅ ¿Van los cuatro parámetros obligatorios en el envío?
- ✅ ¿Responde el proxy al probarlo con
curl? - ✅ ¿Es una salida residencial o de ISP, y no de centro de datos?
- ✅ ¿Resuelves y navegas con la misma salida?
- ✅ ¿Reutilizas el User-Agent devuelto por la API?
- ✅ ¿Está la cookie fijada en el dominio correcto y dentro de su TTL?
Si los siete están en verde y el fallo sigue, busca abajo tu código de error.
Errores que devuelve in.php
El envío falla casi siempre por el proxy. Estos son los cuatro campos obligatorios:
method=cloudflare_challenge
pageurl=https://example.com
proxy=user:pass@host:port
proxytype=HTTP
A diferencia de Turnstile o reCAPTCHA, aquí el proxy no es opcional: sin él la tarea ni entra en la cola. Con SOCKS5 el patrón es idéntico, solo cambia proxytype=SOCKS5.
| Código | Qué está pasando | Qué cambiar |
|---|---|---|
ERROR_BAD_PARAMETERS |
Falta uno de los cuatro campos | Revisa el envío completo, no solo el que crees que falta |
ERROR_PROXY_CONNECTION_FAILED |
CaptchaAI no consigue salir por tu proxy | Pruébalo aparte con curl -x http://user:pass@host:port https://httpbin.org/ip, confirma que admite HTTPS y revisa la lista blanca: quien conecta es CaptchaAI, no tu equipo |
ERROR_PROXY_BANNED |
Cloudflare ya tiene marcada esa IP | Rota a una salida limpia, residencial o de ISP; las IP de centros de datos se marcan de forma agresiva |
ERROR_CAPTCHA_UNSOLVABLE |
No se resolvió ni tras los reintentos | Prueba otra salida, revisa la configuración del sitio y espera 5 minutos |
Si ERROR_PROXY_BANNED y ERROR_CAPTCHA_UNSOLVABLE se alternan en el mismo sitio, lo que falla es la reputación del rango desde el que sales.
La cookie qa_validation_cookie llega, pero el sitio la rechaza
Es el escenario que más tickets genera: la API responde, guardas la cookie y el sitio insiste con el desafío. La cookie queda atada al contexto en el que se generó: misma IP, mismo User-Agent y dentro de su TTL.
El sitio sigue mostrando el desafío: la IP no coincide
Resolviste con un proxy y navegas con otro. Usa exactamente la misma salida después:
# WRONG — different proxy for solving and requests
solve_proxy = "proxy1.example.com:8080"
request_proxy = "proxy2.example.com:8080"
# CORRECT — same proxy for both
proxy = "user:[email protected]:8080"
# Submit solve with this proxy
response = requests.get("https://ocr.captchaai.com/in.php", params={
"key": API_KEY,
"method": "cloudflare_challenge",
"pageurl": "https://example.com",
"proxy": proxy,
"proxytype": "HTTP",
"json": 1
})
# Use the SAME proxy for page requests
session = requests.Session()
session.cookies.set("qa_validation_cookie", solved_cookie)
session.proxies = {"https": f"http://{proxy}"}
El detalle que se escapa está en los pools rotativos: si la salida cambia entre la resolución y la primera solicitud, la cookie nace muerta.
El User-Agent no coincide
El navegador que declaraste al resolver no es el que envías después. Reutiliza el User-Agent de la respuesta, sin retocar ni un número de versión:
solution = result["request"]
# Extract and reuse the exact user agent
user_agent = solution.get("user_agent")
session = requests.Session()
session.headers["User-Agent"] = user_agent # Must match exactly
session.cookies.set("qa_validation_cookie", solution["qa_validation_cookie"])
La cookie caducó
qa_validation_cookie dura poco: entre 15 minutos y 24 horas. Tres hábitos evitan el 403 por sorpresa:
- Guarda la marca de tiempo de cuando obtuviste la cookie
- Renueva antes de que expire, no cuando ya está fallando
- Detecta la página de desafío en la respuesta y vuelve a resolver automáticamente
def make_request(url, session):
response = session.get(url)
if "challenge" in response.text.lower() or response.status_code == 403:
# Cookie expired — re-solve
new_cookie = solve_cloudflare_challenge(url, proxy)
session.cookies.set("qa_validation_cookie", new_cookie)
response = session.get(url)
return response
Cuando el ciclo tarda más de la cuenta
Si CAPCHA_NOT_READY no desaparece, la tarea sigue en curso: consulta el resultado cada 5 segundos, hasta 60 intentos. La SLA de CaptchaAI aquí es de menos de 15 s, pero el ciclo completo suma la latencia de tu salida.
- Usa una salida con menor latencia hacia el sitio objetivo
- Amplía el tiempo de espera antes de dar la tarea por perdida
- Confirma en las cabeceras que la protección sigue siendo esa
Si superas los 5 minutos de forma sistemática, sospecha de la salida antes que del código: hay sitios que alternan Cloudflare Challenge y Turnstile según quién llame.
Un caso real: monitoreo desde una agencia en Latinoamérica
Un equipo que monitorea precios en marketplaces regionales o páginas públicas de trámites levanta sus workers en un servidor europeo mientras el sitio espera tráfico local: el desafío se resuelve, pero a media mañana todo devuelve 403.
La corrección está en el reparto, no en el código: un worker por salida de red, cookie asociada a esa salida y renovación por TTL. Con planes basados en threads el coste queda fijo en USD —BASIC ($15/mes, 5 threads) para un piloto, ADVANCE ($90/mes, 50 threads) si el monitoreo es continuo—. Respeta los términos de servicio del sitio y la normativa de protección de datos aplicable.
Errores de integración más frecuentes
| Error | Resultado | Corrección |
|---|---|---|
| Falta el parámetro proxy | ERROR_BAD_PARAMETERS |
Inclúyelo siempre |
| Salida de centro de datos | ERROR_PROXY_BANNED |
Usa una salida residencial o de ISP |
| User-Agent distinto | Cookie rechazada | Reutiliza el de la respuesta |
| IP distinta | Cookie rechazada | Misma salida en todo el ciclo |
| Dominio de cookie sin definir | La cookie no se envía | Usa .example.com, con punto inicial |
| HTTP en lugar de HTTPS | Conexión fallida | Cloudflare exige HTTPS |
Preguntas frecuentes
¿Cuántos threads necesito si resuelvo varios Cloudflare Challenge a la vez?
Uno por resolución simultánea: diez workers en paralelo piden diez threads. BASIC ($15/mes, 5 threads) incluye resoluciones ilimitadas y se escala por concurrencia, no por volumen.
¿Puedo compartir la misma cookie entre varios workers?
Solo si todos salen por la misma IP y envían el mismo User-Agent. Trata cada par salida + User-Agent como una sesión aparte, con su cookie y su propio TTL.
¿Sirve esta misma configuración para Cloudflare Turnstile?
No del todo. Turnstile devuelve un token de formulario, sin proxy obligatorio ni vinculación a IP, así que estos errores casi desaparecen. No arrastres la lógica de cookies de un flujo al otro.
¿Por qué el error solo aparece en producción y no en mi máquina?
Porque en local sales por tu conexión doméstica y en producción por el rango de tu proveedor cloud, que Cloudflare puntúa peor. Reproduce el fallo en local con la salida de producción antes de tocar el código.