Troubleshooting

Cloudflare Challenge Loop: Mengapa Challenge Terus Berulang

Loop Cloudflare Challenge hampir selalu berarti satu hal: cookie qa_validation_cookie yang Anda pasang sebenarnya valid, tetapi Cloudflare menolaknya karena konteks sesi berubah setelah solve. Cookie itu dibuat untuk kombinasi IP, User-Agent, dan domain tertentu — begitu salah satu berubah, challenge muncul lagi. Jadi masalahnya bukan pada solving CaptchaAI, melainkan pada cara cookie dipakai kembali. Artikel ini menelusuri lima penyebab loop tersebut secara berurutan, lengkap dengan perbaikannya.


Saat CaptchaAI menyelesaikan Cloudflare Challenge, hasilnya adalah cookie qa_validation_cookie. Cloudflare mengikat cookie ini ke tiga sinyal sekaligus:

  1. IP proxy yang dipakai selama solving
  2. User-Agent yang dipakai selama solving
  3. Domain situs target

Cookie hanya diterima jika ketiganya identik antara saat solve dan saat request berikutnya. Ketiga sinyal ini adalah cara Cloudflare memastikan cookie tidak dipindah ke sesi atau mesin lain. Jika salah satu berbeda — misalnya scraper Anda berjalan di region cloud Jakarta (ap-southeast-3) sementara solve tadi memakai egress lain — Cloudflare menganggap cookie tidak sah dan mengembalikan halaman challenge. Loop yang terasa acak itu sebenarnya deterministik: cari sinyal mana yang bergeser, dan loop berhenti.

Sebelum masuk ke detail, berikut peta cepat lima penyebab loop dan perbaikannya:

Penyebab Gejala khas Perbaikan singkat
User-Agent berbeda Loop langsung sejak request pertama Pakai satu konstanta User-Agent
IP proxy berubah Loop muncul saat egress dirotasi Sematkan ke sticky session
Domain cookie salah Loop hanya di subdomain tertentu Awali domain dengan titik
Cookie kedaluwarsa Loop muncul di tengah job panjang Solve ulang sebelum 15 menit
TLS tidak menyerupai Chrome Cookie valid tapi tetap ditolak Pakai curl_cffi

Penyebab 1: User-Agent berbeda antara solve dan request

Ini penyebab yang paling sering muncul. User-Agent yang Anda kirim ke CaptchaAI harus sama persis, karakter demi karakter, dengan User-Agent pada request Anda sesudahnya. Perbedaan sekecil nomor versi Chrome pun cukup untuk membuat cookie ditolak.

  • Gejala: challenge kembali muncul sejak request pertama setelah solve.
  • Akar masalah: string User-Agent ditulis dua kali dan tidak persis sama.
  • Perbaikan: simpan satu konstanta dan gunakan di solve maupun request.
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": "cloudflare_challenge",
    "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: Gunakan User-Agent YANG SAMA dalam request berikutnya
session = requests.Session()
session.headers["User-Agent"] = USER_AGENT  # Must match step 1
session.cookies.set("qa_validation_cookie", cf_clearance_value, domain=".example.com")
resp = session.get("https://example.com")

Simpan satu konstanta USER_AGENT dan gunakan referensi yang sama di kedua tempat. Jangan pernah menuliskan string User-Agent dua kali secara manual — di situlah selisih satu digit menyelinap masuk.


Penyebab 2: IP proxy berubah di tengah sesi

Cookie qa_validation_cookie terikat pada IP yang men-solve challenge. Jika request berikutnya keluar dari IP yang berbeda, cookie langsung ditolak. Kasus ini sering terjadi tanpa disadari ketika Anda memakai rotasi egress: solve keluar dari satu IP, lalu request produksi keluar dari IP lain.

  • Gejala: solving berhasil, tetapi loop muncul saat pool egress berputar.
  • Perbaikan: kunci solve dan browsing ke egress yang sama.
PROXY = "host:port:user:pass"

# Solve with this proxy
solve_data = {
    "key": "YOUR_API_KEY",
    "method": "cloudflare_challenge",
    "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"
}

Penting: Jika Anda memakai rotasi egress jaringan yang diotorisasi, sematkan sesi ke satu sticky session. IP harus tetap sama sepanjang hidup cookie — dari solve sampai request terakhir yang memakainya. Untuk tim scraping yang men-deploy worker di beberapa region, pastikan worker yang men-solve dan worker yang browsing berbagi egress yang sama, bukan sekadar berada di VPC yang sama.


Cookie harus dipasang pada domain yang tepat dengan atribut yang benar. Kesalahan klasik adalah men-set cookie tanpa titik di depan domain, sehingga cookie tidak berlaku untuk subdomain seperti www. atau api..

  • Gejala: challenge lolos di satu host tetapi loop di subdomain lain.
  • Perbaikan: awali domain dengan titik, misalnya .example.com.
# WRONG — setting on wrong domain
session.cookies.set("qa_validation_cookie", value, domain="example.com")

# CORRECT — include the dot prefix for subdomain coverage
session.cookies.set("qa_validation_cookie", value, domain=".example.com")

# Or set all cookies returned by CaptchaAI
for cookie_str in result.get("cookies", "").split(";"):
    if "qa_validation_cookie" in cookie_str:
        name, val = cookie_str.strip().split("=", 1)
        session.cookies.set(name.strip(), val.strip(), domain=".example.com")

Cara paling aman adalah menyalin semua cookie yang dikembalikan CaptchaAI apa adanya, bukan menyusun ulang domain secara manual.


Cookie qa_validation_cookie punya masa berlaku terbatas — biasanya 15–30 menit, dan sebagian situs menetapkan durasi lebih pendek. Setelah lewat, Cloudflare kembali menampilkan challenge. Pada job scraping yang berjalan lama, ini terlihat seperti loop yang muncul tiba-tiba di tengah proses padahal semuanya sempat berjalan lancar.

  • Gejala: sesi berjalan mulus lalu tiba-tiba loop setelah beberapa menit.
  • Perbaikan: lacak umur cookie dan solve ulang secara proaktif.

Perbaikan: Lacak umur cookie dan solve ulang sebelum kedaluwarsa, jangan menunggu request pertama yang gagal.

import time

last_solve_time = None
COOKIE_TTL = 900  # 15 minutes

def get_cf_clearance():
    global last_solve_time
    if last_solve_time and (time.time() - last_solve_time) < COOKIE_TTL:
        return  # Cookie still valid

    # Solve again
    qa_validation_cookie = solve_cloudflare_challenge()
    session.cookies.set("qa_validation_cookie", qa_validation_cookie, domain=".example.com")
    last_solve_time = time.time()

Setel COOKIE_TTL sedikit lebih pendek dari masa berlaku sebenarnya sebagai margin aman, misalnya 900 detik untuk cookie 15 menit.


Penyebab 5: TLS sinyal browser Python tidak menyerupai Chrome

Cloudflare juga memeriksa TLS sinyal browser. Library requests bawaan Python punya TLS sinyal browser yang berbeda dari Chrome, sehingga sebagian situs menolak request meski qa_validation_cookie sepenuhnya valid. Ini penyebab loop yang paling sulit dikenali, karena keempat sinyal sebelumnya sudah benar tetapi challenge tetap muncul.

  • Gejala: User-Agent, IP, domain, dan umur cookie sudah benar, loop tetap ada.
  • Perbaikan: ganti requests dengan curl_cffi atau tls-client.

Perbaikan: Gunakan curl_cffi atau tls-client agar TLS sinyal browser Anda menyerupai browser sungguhan.

pip install curl_cffi
from curl_cffi import requests as curl_requests

session = curl_requests.Session(impersonate="chrome120")
session.cookies.set("qa_validation_cookie", value, domain=".example.com")
resp = session.get("https://example.com")

Pastikan nilai impersonate (misalnya chrome120) sejalan dengan versi Chrome pada User-Agent Anda, supaya kedua sinyal itu konsisten.


Checklist debug loop Cloudflare Challenge

Telusuri dari atas ke bawah — begitu satu jawaban "Tidak", perbaiki dulu sebelum lanjut:

Challenge terus berulang
    ↓
User-Agent di solve request cocok dengan browsing request? → Tidak → Samakan User-Agent
    ↓ Ya
Proxy IP sama untuk solve dan browse? → Tidak → Pin proxy IP (sticky session)
    ↓ Ya
Cookie di-set di domain yang benar (.example.com)? → Tidak → Perbaiki domain
    ↓ Ya
Cookie kurang dari 15 menit? → Tidak → Solve ulang challenge
    ↓ Ya
TLS sinyal browser cocok browser? → Tidak → Gunakan curl_cffi atau tls-client
    ↓ Ya
Situs mungkin punya bot detection tambahan → Gunakan headless browser

Catatan kepatuhan singkat: selaras dengan UU Pelindungan Data Pribadi (UU 27/2022), pastikan Anda hanya mengambil data yang memang berhak Anda proses dan hindari data pribadi di balik login.


Pertanyaan umum

Karena cookie yang valid pun ditolak jika salah satu dari IP, User-Agent, atau domain berbeda dari saat solve. Cek ketiganya lebih dulu; pada mayoritas kasus, User-Agent yang tidak identik adalah biang loop.

Sebaiknya pakai egress datacenter atau egress jaringan yang diotorisasi?

Yang menentukan bukan jenisnya, melainkan konsistensinya. IP apa pun yang dipakai untuk solve harus dipakai lagi untuk browsing, disematkan ke satu sticky session sepanjang masa berlaku cookie.

Apakah curl_cffi menghilangkan kebutuhan headless browser?

Untuk banyak situs, ya — curl_cffi menyamakan TLS sinyal browser tanpa beban penuh sebuah browser. Jika situs punya bot detection tambahan di sisi JavaScript, barulah headless browser diperlukan.

Bagaimana cara tahu penyebab loop yang saya alami?

Ikuti checklist debug dari atas ke bawah dan ubah satu variabel setiap kali. Isolasi seperti ini jauh lebih cepat daripada mengganti banyak hal sekaligus, karena loop selalu bersumber dari satu sinyal yang bergeser.

Umumnya 15–30 menit, sebagian situs lebih pendek. Solve ulang secara proaktif sebelum kedaluwarsa alih-alih menunggu request gagal.


Panduan terkait

Komentar dinonaktifkan untuk artikel ini.