Getting Around Cloudflare Protection Using Puppeteer and FlareSolverr

Help with Cloudflare Bypass Issues

I have been trying to scrape a website for the last month but keep running into Cloudflare problems. When I use just Puppeteer by itself, I get stuck on a page that says “Waiting for the website to respond” pretty often.

I tried different methods to fix this:

  • Using Puppeteer with proxy rotation
  • Adding the stealth plugin for puppeteer-extra
  • Switching to puppeteer-real-browser with proxies
  • Combining puppeteer-real-browser with FlareSolverr and proxy rotation

My Current Setup

Right now I am using FlareSolverr to make a request first. Then I take the cookies and user agent from that request and give them to Puppeteer. But I have two main problems:

  1. FlareSolverr cannot solve the challenge - When it finds a Cloudflare challenge, it just times out and gives me an error message

  2. Puppeteer still gets blocked - Even when FlareSolverr works and I copy the cookies and user agent, Puppeteer still hits the Cloudflare page

It seems like FlareSolverr might not be finding the challenge correctly, so it does not get the right cookies.

What am I missing here? Is there a better way to make Puppeteer work with Cloudflare protection?

let solverResponse;
let retryCount = 0;
const maxRetries = 3;

// Make request through solver service
while (retryCount < maxRetries) {
  try {
    const requestOptions = {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        command: "get.request",
        targetUrl: pageUrl,
        timeout: 8000,
        sessionToken: solverSession,
      }),
    };

    let apiResponse = await fetch("http://localhost:8191/v1", requestOptions);
    solverResponse = await apiResponse.json();

    if (solverResponse?.status === "failed") {
      throw new Error(solverResponse?.error ?? "Solver service failed");
    }

    break;
  } catch (err) {
    retryCount++;
    if (retryCount === maxRetries) {
      throw new Error(`Request failed after ${retryCount} tries: ${err.message}`);
    }
    await new Promise((wait) => setTimeout(wait, 2000));
  }
}

if (!solverResponse) throw new Error("No response from solver service");

const sessionCookies = solverResponse.result.cookies;
const browserAgent = solverResponse.result.userAgent;

if (!browserAgent) throw new Error("Missing user agent");

if (sessionCookies.length > 0) {
  await puppeteerBrowser.setCookie(
    ...sessionCookies.map((item) => ({ ...item, expires: item?.expiry || 0 }))
  );
}

await currentPage.setUserAgent(browserAgent);

await sleep(Math.random() * 5000 + 2000);
await currentPage.goto(pageUrl, { waitUntil: "domcontentloaded" });

const pageHtml = await currentPage.content();
return pageHtml;

Your code looks mostly correct but there’s a critical timing issue you might be missing. Cloudflare sometimes serves different challenge types that take varying amounts of time to complete, and your 8000ms timeout might not be sufficient for the more complex ones. I’ve found that using session persistence is crucial - make sure you’re reusing the same sessionToken across multiple requests rather than creating new ones each time. Also worth checking if the target site has additional protections like rate limiting that trigger even after successful challenge completion. One thing that helped me was adding a longer delay between the FlareSolverr request and the Puppeteer navigation, sometimes up to 10-15 seconds. The browser fingerprinting detection has gotten more sophisticated recently, so even small differences in how you apply the cookies or navigate to the page can trigger a new challenge cycle.

I had similar struggles with this exact setup a few months back. The issue you’re describing usually happens because Cloudflare tracks browser fingerprints beyond just cookies and user agent. Even when FlareSolverr successfully solves the challenge, Puppeteer creates a different browser fingerprint that Cloudflare detects as suspicious. What worked for me was switching to undetected-chromedriver for Python or using playwright with real browser binaries instead of the bundled chromium. The key insight is that you need to match not just the cookies but the entire browser environment including viewport size, installed plugins, and even the order of HTTP headers. Another approach that helped was running everything through the same browser instance - instead of using FlareSolverr separately, I modified it to keep the browser session alive and then connected Puppeteer to that existing session using the debugging port.

flaresolverr can be finicky tbh. try increasing your timeout to like 30000+ and make sure you’re using the latest version. also double check that you’re setting the cookies on the right domain - sometimes cloudflare uses different subdomains for challenges