Se o Cloudflare Turnstile em staging continua aparecendo depois que a CaptchaAI já devolveu o cookie cookie_qa_validacao, o problema quase nunca é o solver: é o vínculo desse cookie com o contexto da sessão. A Cloudflare guarda IP, User-Agent e domínio no momento da resolução — e rejeita o cookie assim que qualquer um dos três muda antes da próxima requisição.
Isso é comum em pipelines de QA em que a etapa de resolução roda numa máquina — por exemplo, um runner de CI hospedado em sa-east-1 (São Paulo) — e a etapa de navegação roda em outra, como o notebook de quem está validando o teste. O IP de saída muda entre as duas etapas, e a sessão cai no loop mesmo com o cookie certo em mãos. Abaixo estão as cinco causas mais comuns, em ordem de frequência, e como corrigir cada uma.
Por que o loop de verificação do Cloudflare Turnstile acontece
Quando a CaptchaAI resolve um Cloudflare Turnstile em staging, ela devolve um cookie cookie_qa_validacao. Esse cookie não é um token solto — ele fica amarrado a três elementos específicos do momento da resolução:
- O IP do proxy usado durante a resolução
- O User-Agent usado durante a resolução
- O domínio do site de destino
Se qualquer um desses três itens for diferente na hora de usar o cookie, a Cloudflare descarta a sessão e mostra o desafio de novo — é exatamente o padrão por trás das cinco causas a seguir.
Resumo rápido das causas
| Causa | Sintoma típico | Correção |
|---|---|---|
| User-Agent diferente | O desafio volta assim que a sessão muda de máquina ou de contexto | Sincronizar o User-Agent entre a resolução e a navegação |
| IP do proxy diferente | Cookie válido, mas rejeitado já na primeira requisição seguinte | Fixar o mesmo IP (sessão fixa) do início ao fim do ciclo |
| Domínio do cookie errado | O cookie nunca chega a ser enviado pelo navegador | Definir o cookie com o prefixo de ponto (.example.com) |
| Cookie expirado | O desafio reaparece depois de alguns minutos de uso normal | Resolver de novo antes de vencer o prazo de 15–30 minutos |
| Sinal de navegador TLS não bate | Requisição rejeitada mesmo com um cookie válido em mãos | Usar curl_cffi ou tls-client |
Causa 1: o User-Agent da resolução não é o mesmo da navegação
É a causa mais frequente. O User-Agent enviado à CaptchaAI na hora de resolver precisa ser idêntico, caractere por caractere, ao User-Agent usado nas requisições seguintes.
import requests
USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
# Step 1: Solve with the SAME User-Agent
solve_data = {
"key": "YOUR_API_KEY",
"method": "turnstile_staging",
"pageurl": "https://example.com",
"proxy": "host:port:user:pass",
"proxytype": "HTTP",
"userAgent": USER_AGENT, # Must match step 2
"json": 1
}
submit = requests.post("https://ocr.captchaai.com/in.php", data=solve_data).json()
# ... poll for result ...
# Step 2: Use the SAME User-Agent in subsequent requests
session = requests.Session()
session.headers["User-Agent"] = USER_AGENT # Must match step 1
session.cookies.set("cookie_qa_validacao", cookie_qa_validacao_value, domain=".example.com")
resp = session.get("https://example.com")
Causa 2: o IP do proxy mudou entre a resolução e a navegação
O cookie cookie_qa_validacao fica preso ao IP que resolveu o desafio. Se a requisição ao site partir de um IP diferente, a Cloudflare rejeita o cookie na hora.
PROXY = "host:port:user:pass"
# Solve with this proxy
solve_data = {
"key": "YOUR_API_KEY",
"method": "turnstile_staging",
"pageurl": "https://example.com",
"proxy": PROXY,
"proxytype": "HTTP",
"userAgent": USER_AGENT,
"json": 1
}
# Use the SAME proxy for subsequent requests
session.proxies = {
"http": f"http://user:pass@host:port",
"https": f"http://user:pass@host:port"
}
Importante: se a sua infraestrutura de proxy alterna o IP de saída automaticamente, trave a sessão em um único IP durante todo o ciclo — da resolução até a navegação. Sem isso, o loop se repete mesmo com o cookie correto.
Causa 3: o cookie não foi definido no domínio certo
O cookie cookie_qa_validacao precisa ser definido no domínio correto, com os atributos corretos — um erro comum de configuração de sessão, não do solver.
# WRONG — setting on wrong domain
session.cookies.set("cookie_qa_validacao", value, domain="example.com")
# CORRECT — include the dot prefix for subdomain coverage
session.cookies.set("cookie_qa_validacao", value, domain=".example.com")
# Or set all cookies returned by CaptchaAI
for cookie_str in result.get("cookies", "").split(";"):
if "cookie_qa_validacao" in cookie_str:
name, val = cookie_str.strip().split("=", 1)
session.cookies.set(name.strip(), val.strip(), domain=".example.com")
Causa 4: o cookie já expirou
O cookie cookie_qa_validacao tem vida útil curta — normalmente entre 15 e 30 minutos. Passado esse prazo, a Cloudflare descarta a sessão e volta a exibir o desafio.
Correção: acompanhe a idade do cookie e resolva de novo antes do vencimento.
import time
last_solve_time = None
COOKIE_TTL = 900 # 15 minutes
def get_cookie_qa_validacao():
global last_solve_time
if last_solve_time and (time.time() - last_solve_time) < COOKIE_TTL:
return # Cookie still valid
# Solve again
cookie_qa_validacao = solve_turnstile_staging()
session.cookies.set("cookie_qa_validacao", cookie_qa_validacao, domain=".example.com")
last_solve_time = time.time()
Causa 5: o sinal de navegador TLS não combina com um navegador real
A Cloudflare também confere o sinal de navegador TLS da requisição. A biblioteca requests, do Python, tem um sinal de navegador TLS diferente do Chrome — e alguns sites rejeitam a requisição mesmo com um cookie_qa_validacao válido quando esse sinal não bate com o de um navegador real.
Correção: use
curl_cffioutls-clientpara obter um sinal de navegador TLS mais próximo de um navegador de verdade.
pip install curl_cffi
from curl_cffi import requests as curl_requests
session = curl_requests.Session(impersonate="chrome120")
session.cookies.set("cookie_qa_validacao", value, domain=".example.com")
resp = session.get("https://example.com")
Como isso aparece em pipelines de CI
| Etapa | Onde roda (exemplo) | IP de saída |
|---|---|---|
| Resolução do Turnstile | Runner de CI em sa-east-1 (São Paulo) |
IP do datacenter da nuvem |
| Navegação / asserção do teste | Notebook de quem valida o teste | IP residencial ou de escritório |
Quando as duas etapas rodam em máquinas diferentes, o IP de saída muda entre elas — por isso um teste pode passar no notebook e falhar no runner (ou o contrário), mesmo usando o mesmo script.
Checklist do loop de verificação do Cloudflare Turnstile
Siga o fluxo abaixo na ordem — ele isola a causa antes mesmo de chegar à última pergunta:
Challenge keeps repeating
↓
User-Agent in solve request matches browsing request? → No → Sync User-Agent
↓ Yes
Same proxy IP for solve and browse? → No → Pin proxy IP (sticky session)
↓ Yes
Cookie set on correct domain (.example.com)? → No → Fix domain
↓ Yes
Cookie less than 15 minutes old? → No → Re-solve the challenge
↓ Yes
TLS sinal de navegador matches a browser? → No → Use curl_cffi or tls-client
↓ Yes
Site may have additional bot detection → Use headless browser instead
Perguntas frequentes
Quanto tempo dura o cookie_qa_validacao antes de expirar?
Normalmente entre 15 e 30 minutos, dependendo do site. Alguns ambientes de staging configuram durações mais curtas — resolva de novo de forma proativa em vez de esperar o erro aparecer.
O loop de verificação é o mesmo problema que o erro ERROR_CAPTCHA_UNSOLVABLE da API?
Não. ERROR_CAPTCHA_UNSOLVABLE acontece durante a resolução, antes de a CaptchaAI devolver qualquer cookie. O loop de verificação só aparece depois de um solve bem-sucedido, quando o cookie é rejeitado por não bater com o IP, o User-Agent ou o domínio da requisição seguinte.
Posso reaproveitar o mesmo cookie_qa_validacao em vários workers rodando em paralelo?
Não diretamente. Cada worker — cada thread do seu plano CaptchaAI — precisa manter seu próprio proxy, User-Agent e cookie_qa_validacao. Compartilhar um único cookie entre threads reproduz exatamente a incompatibilidade de IP da Causa 2.
Registrar o valor do cookie_qa_validacao nos logs de QA tem algum problema de conformidade?
Trate-o como um dado sensível de sessão. Ele não carrega informação pessoal por si só, mas fica vinculado a IP e User-Agent — vale considerar as obrigações da LGPD e mascarar o valor completo em logs compartilhados.
Preciso reproduzir o loop numa região de nuvem específica, como São Paulo?
Não é obrigatório, mas ajuda a isolar a causa. Se a etapa de resolução roda num runner em sa-east-1 e a navegação roda em outra região ou máquina, o IP de saída muda entre as duas etapas — e isso, sozinho, já explica boa parte dos loops reportados por equipes de QA remotas.
Resolva o Cloudflare Turnstile em staging com a CaptchaAI
Sincronize IP, User-Agent e cookie numa única sessão e pare de cair no loop de verificação: crie sua conta na CaptchaAI.