Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Most Crawl4AI screenshot failures can be isolated to one stage: the Playwright browser is not installed or cannot launch, the page is not ready when captured, full-page stitching runs into an unbounded document, or the site serves a bot-check page instead of the requested content. Start with a minimal crawl in the same environment that fails, inspect result.error_message and the length of result.screenshot, then change only the settings for the failing stage.

Know which part failed

Crawl4AI separates browser startup from capture. BrowserConfig controls the engine, executable, viewport, device scale, proxy and launch behavior. CrawlerRunConfig controls whether a screenshot is requested and when or how the page is captured. A valid selector or extraction strategy cannot repair a browser that never launched.

Symptom Likely stage First check
Executable doesn't exist, google-chrome not found, or missing chrome-headless-shell Installation, cache, path, or image mismatch Install the matching Playwright browser in the runtime and record the attempted executable path.
result.screenshot is empty Screenshot option or page readiness Confirm screenshot=True, add a wait, and test a static URL.
Image is white, partially rendered, or missing late-loading images Rendering timing, viewport, or lazy content Increase the documented wait and test viewport capture before full-page capture.
Image is cut off or full-page capture times out Page height or scroll stitching Use force_viewport_screenshot=True, then tune full-page limits.
Browser launches but content is a challenge page or altered page Access or anti-bot response Save the returned HTML and diagnose the site response separately from browser installation.

Establish a clean baseline in the failing environment

Run the supported setup inside the same virtual environment, container, CI runner, or hosted notebook that executes your crawler. Installing Chromium on your laptop does not make it available in a separate Docker image.

pip install -U crawl4ai
crawl4ai-setup
python -m playwright install --with-deps chromium
crawl4ai-doctor

crawl4ai-setup installs Playwright and related dependencies. The doctor routine launches a Chromium crawl with screenshot=True; a doctor failure therefore points to the runtime before your application selectors or extraction code.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
#1 Best Overall
Elebase USB to USB C Adapter for iPhone 18 Pro Max,USBC Car Charger Adapter
  • Read Before You Buy — No Video Output: These adapters support charging and USB 2.0 data transfer, but cannot transmit video signals. Except for standard USB webcams (which use USB data only), they are not compatible with HDMI/DisplayPort cables, video-capable USB-C hubs, or docking stations with video output.
  • Convert USB-A Ports to USB-C: Designed to connect USB-C earphones, cables, flash drives, card readers, and other USB-C accessories to standard USB-A ports. Plug-and-play with no drivers or software required.
  • Aluminum Alloy Housing: Built with a sturdy aluminum alloy shell that aids in heat dissipation and protects against daily wear and scratches. Designed to maintain a stable and secure connection.
  • Compact & Travel-Friendly: The ultra-compact design allows the adapter to stay plugged into your device without blocking adjacent ports or adding bulk, reducing wear and tear on your original USB ports.
  • 12-Month Warranty: Backed by a 12-month manufacturer warranty for peace of mind. Designed to meet strict quality control standards for reliable everyday performance.

Use this smallest useful test. It deliberately uses a visible browser and verbose logging so launch and rendering problems are observable.

import asyncio
from crawl4ai import AsyncWebCrawler, BrowserConfig, CrawlerRunConfig

async def main():
    browser = BrowserConfig(
        browser_type="chromium",
        headless=False,
        verbose=True,
        viewport_width=1280,
        viewport_height=720,
    )
    run = CrawlerRunConfig(
        screenshot=True,
        screenshot_wait_for=2.0,
    )
    async with AsyncWebCrawler(config=browser) as crawler:
        result = await crawler.arun("https://example.com", config=run)
        print("success:", result.success)
        print("error:", result.error_message)
        print("screenshot bytes (base64):", len(result.screenshot or ""))

asyncio.run(main())

A successful baseline should report success: True and a nonzero screenshot string. Keep this test unchanged while you troubleshoot; add your real URL only after it works.

Repair missing Chromium or executable errors

Install in the runtime, not just during local development

Errors such as Executable doesn't exist and “browser executable not found” mean Playwright cannot start. Repeat the setup commands in the image or worker that actually runs the job. In a multi-stage Docker build, make sure the browser cache created in the build stage is copied into the final stage, or run the install command in the final image.

Align Crawl4AI, Playwright, and the image

Pin the Crawl4AI version and the image tag together. A hosted image can contain a different Playwright revision than your Python environment expects. Crawl4AI issue #503 describes missing Playwright binaries in a hosted environment; issue #875 describes an image searching for google-chrome; issue #2064 describes a 0.9.1 image expecting a headless-shell binary that was not present. These are path and packaging failures, not page-selector failures.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Check cache and custom Chrome paths

  • Verify the Playwright cache directory exists, is readable, and is not deleted between build and runtime.
  • Preserve the complete launch log, including the executable path Playwright attempted.
  • If the platform supplies its own Chrome binary, configure Crawl4AI/Playwright to use that exact path instead of assuming automatic detection will find it.
  • Do not change screenshot selectors until a plain Chromium launch succeeds.

Docker resource checks

If Chromium starts and then exits, inspect container memory, shared-memory size, and sandbox messages. Give the browser adequate shared memory and memory before changing capture code. A browser process that is killed by the container can look like a random screenshot timeout.

Fix an empty or blank screenshot

Confirm the request is enabled

The capture switch is CrawlerRunConfig(screenshot=True). Browser launch settings belong in BrowserConfig; putting a screenshot option in the wrong object will not enable capture.

Rank #2
Anker USB-C Hub, 5-in-1 USB Hub for Laptops, 4K HDMI Multiport Adapter
  • 5-in-1 USB-C Hub: Experience comprehensive connectivity featuring a Power Delivery input, two USB-A 2.0 ports, a USB-A 3.0 port, and an HDMI port. (Note: The USB-C power delivery input port is only for connecting an external wall charger to power your laptop and cannot power peripheral devices.)
  • 90W Pass-Through Charging: Achieve optimal charging with 90W pass-through power to your laptop, supported by a total input of 100W, with the hub reserving 10W for operational efficiency. (Note: Wall charger not included.)
  • Quick Data Transfers: Accelerate your productivity with rapid data transfers using a high-speed 5Gbps USB 3.0 port and two 480Mbps USB 2.0 ports.
  • 4K HDMI Display: Enhance your visual experience with a hub capable of delivering 4K resolution at 30Hz in both mirror and extend modes. Please note that this hub is compatible with MacBook (macOS 12 and newer), Windows 10 and 11, ChromeOS, and laptops equipped with DP Alt Mode and Power Delivery. Note: This device is not compatible with Linux.
  • What You Get: Anker USB-C Hub (5-in-1, 4K HDMI), welcome guide, 18-month warranty, and our friendly customer service.

Wait for the page to render

Static HTML may be available immediately while JavaScript applications, fonts, images, and consent dialogs are still changing the page. Start with screenshot_wait_for=2.0, then use the smallest wait that consistently produces the required state. For JavaScript-heavy pages, combine an appropriate page wait or delay_before_return_html with the screenshot wait. Excessive delays increase crawl time for every URL.

Use a static control URL

Run the baseline against https://example.com. If that image is valid but your target is blank, the browser and encoder are working; investigate target-page readiness, redirects, consent overlays, or an access challenge.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Check viewport and device scale

Set a deterministic viewport_width and viewport_height. Device scale factor changes output dimensions and memory use, so compare the local and failing environments rather than assuming identical pixel sizes.

Capture full pages without cutoffs or runaway waits

First separate a viewport problem from a full-page problem:

run = CrawlerRunConfig(
    screenshot=True,
    screenshot_wait_for=2.0,
    force_viewport_screenshot=True,
)

If the viewport image is correct, tune the full-page controls instead of reinstalling the browser.

Control page height and scrolling

  • screenshot_height_threshold determines when a document is treated as tall enough for full-page handling.
  • scan_full_page enables the full-page scan/stitching behavior.
  • scroll_delay gives lazy-loaded content time to appear after each scroll.
  • max_scroll_steps caps work on pages that continually grow.

Very tall feeds, infinite-scroll pages, and pages that append content while you scroll may never reach a stable bottom. Cap the scroll steps or capture bounded sections. Reserve full-page output for pages with a practical height limit; use viewport captures for monitoring.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #3
Sale
Anker USB C Hub, 7in1 Multi-Port USB Adapter, 4K@60Hz USBC to HDMI Splitter
  • Sleek 7-in-1 USB-C Hub: Features an HDMI port, two USB-A 3.0 ports, and a USB-C data port, each providing 5Gbps transfer speeds. It also includes a USB-C PD input port for charging up to 100W and dual SD and TF card slots, all in a compact design.
  • Flawless 4K@60Hz Video with HDMI: Delivers exceptional clarity and smoothness with its 4K@60Hz HDMI port, making it ideal for high-definition presentations and entertainment. (Note: Only the HDMI port supports video projection; the USB-C port is for data transfer only.)
  • Double Up on Efficiency: The two USB-A 3.0 ports and a USB-C port support a fast 5Gbps data rate, significantly boosting your transfer speeds and improving productivity.
  • Fast and Reliable 85W Charging: Offers high-capacity, speedy charging for laptops up to 85W, so you spend less time tethered to an outlet and more time being productive.
  • What You Get: Anker USB-C Hub (7-in-1), welcome guide, 18-month warranty, and our friendly customer service.

When local works but CI or Docker fails

Re-run the minimal test inside the failing environment and compare these values:

  • Crawl4AI, Playwright, and browser-engine versions.
  • Installed executable path and image tag.
  • Viewport width, viewport height, and device scale factor.
  • Proxy, custom headers, user agent, and network policy.
  • Container shared memory, available memory, and sandbox configuration.

Record the exact Playwright error text, not only a generic job failure. A reproducible health-check URL and pinned image make dependency changes detectable before production crawls are affected.

Distinguish an access challenge from a screenshot-engine failure

A browser can launch normally yet receive a CAPTCHA, bot-check page, login wall, or an intentionally altered response. In that case result.screenshot may be valid while showing the wrong page. Save the returned HTML, final URL, and screenshot and inspect what the server actually delivered.

For legitimate access testing, the Crawl4AI undetected-browser guidance suggests headful mode, reasonable waits, simulate_user, magic, and, where justified, the undetected adapter. These techniques consume more resources and cannot guarantee access. Always respect robots.txt and the website’s terms of service.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use a configuration split you can reason about

Concern Configuration Examples
Browser launch BrowserConfig Chromium versus another engine, headless mode, viewport, device scale, proxy, extra arguments, stealth.
Capture and readiness CrawlerRunConfig screenshot, screenshot wait, page wait, delay before HTML, viewport/full-page mode, scroll limits.

Keeping this split makes diagnosis mechanical: launch errors require environment or BrowserConfig work; blank or incomplete images require readiness and capture settings in CrawlerRunConfig.

Build a stable production pattern

  1. Keep a small health-check URL and run it after every dependency or image change.
  2. Log result.success, result.error_message, browser/image versions, viewport dimensions, and whether a screenshot string was returned.
  3. Use deterministic viewport and device-scale settings so image dimensions are comparable between workers.
  4. Set a nonzero screenshot wait only for pages that need it; unnecessary delay multiplies operating cost.
  5. Prefer viewport captures for monitoring and bounded full-page captures for documents whose height is known.
  6. Retain the exact failing Playwright launch message when escalating a CI or Docker issue.

Or skip the browser setup

If maintaining matching Playwright binaries in every CI job or container is not worthwhile, ScreenshotNeo is a hosted website screenshot API and MCP server. It accepts one GET request and returns PNG, JPEG, WebP, or PDF. Before capture it accepts the cookie/consent banner like a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each cleanup step can be disabled.

Only clean shots are billed. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, and response headers identify the page verdict and whether it was billed. Its MCP server exposes take_screenshot, get_page_info, and capture_pdf for Claude, Cursor, and other MCP clients.

Rank #4
Sale
UGREEN USB to USB C Adapter Combo 4-Pack, 10Gbps USB C Converter Space Gray
  • Dual Converters, Infinite Potential:Includes 2× USB C male to USB A female adapters and 2× USB A male to USB C female adapters. Perfect for a wide range of uses—tablets with Bluetooth keyboards, expand USB ports on macbook, and more. Two different converters for all your daily needs
  • Next-Level 10Gbps & 3A Charging: No more slow 480Mbps, this usb to usb c adapter has a transfer speed of up to 10Gbps, allowing you to do more transferring in less time. This usb adapter fits both USB A and USB C charger, supporting up to 3A fast charging
  • Upgraded Exquisite Craftsmanship: With an aluminum alloy housing and metal connector, the usbc to usb adapter is extremely durable and sturdy. Rigorously tested to withstand more than 10,000 times of plugging and unplugging, ensuring long-lasting performance
  • Broad Compatible: The usb c to usb adapter widely supports all USB C/ USB A devices like laptops, tablets, cellphones, car chargers, and phone chargers. Such as compatible with MacBook Pro/Air 2023/2022, Thunderbolt 4/3 Devices,Apple MagSafe Watch 9/8/7/SE/Ultra, iPad Pro 2022/2021, Samsung Galaxy S23/S20/S10, and iPhone 17/16/15 Pro. Plug and play
  • Please Note: To reach 10Gbps speed, keep the cable under 3.3 ft. For USB A Male to USB C adapters, try flipping the USB C connector. USB C Male to USB A adapters support bidirectional 10Gbps transfer within 3.3 ft
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

See the ScreenshotNeo documentation for all request parameters. The same endpoint supports full-page capture with lazy images loaded, CSS-selector element capture, dark mode, 12 device presets or any viewport, retina scale, PDF paper size/margins/landscape/page ranges, HTML/CSS-to-image, custom CSS and JavaScript, pre-capture clicks, hidden selectors, waits for a selector, delay or network idle, blocked ads/trackers/requests/resource types, custom headers/cookies/user agent/Authorization, timezone and geolocation, transparent backgrounds, image resizing, caller-selected cache TTL, signed links for public <img> tags, asynchronous jobs with signed webhooks, bulk capture of up to 100 URLs per call, a usage API, and an OpenAPI specification. Parameter names used by other screenshot APIs also work to ease migration.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
Plan Allowance or price
Free 1,000 shots/month, no card
Starter $5 for 3,000 shots
Growth $15 for 15,000 shots
Pro $39 for 60,000 shots
Scale $99 for 250,000 shots
Business $249 for 1,000,000 shots

Every feature is included on every plan, and yearly billing gives two months free. Create a free ScreenshotNeo account to get 1,000 screenshots a month with no card; paid plans start at $5 for 3,000 shots.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

FAQ

Does an empty screenshot string prove the target page was empty?

No. It can also mean capture was disabled, the page was not ready, or the browser failed before encoding. Compare result.success, error_message, and a static control URL.

Should headless mode stay disabled in production?

No. Use headless=False while diagnosing so launch and rendering are visible, then return to headless operation once the baseline is stable.

Why can a valid image still be the wrong content?

The server may have returned a bot-check, login page, or other altered response. Inspect the final URL and HTML; this is an access problem rather than a screenshot-encoding problem.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

What is the safest way to handle an infinite-scroll page?

Use viewport capture or a bounded number of scroll steps. A page that keeps appending content has no reliable full-page endpoint.

Best Value
Anker USB C Hub, 5-in-1 USBC to HDMI Splitter with 4K Display
  • 5-in-1 Connectivity: Equipped with a 4K HDMI port, a 5 Gbps USB-C data port, two 5 Gbps USB-A ports, and a USB C 100W PD-IN port. Note: The USB C 100W PD-IN port supports only charging and does not support data transfer devices such as headphones or speakers.
  • Powerful Pass-Through Charging: Supports up to 85W pass-through charging so you can power up your laptop while you use the hub. Note: Pass-through charging requires a charger (not included). Note: To achieve full power for iPad, we recommend using a 45W wall charger.
  • Transfer Files in Seconds: Move files to and from your laptop at speeds of up to 5 Gbps via the USB-C and USB-A data ports. Note: The USB C 5Gbps Data port does not support video output.
  • HD Display: Connect to the HDMI port to stream or mirror content to an external monitor in resolutions of up to 4K@30Hz. Note: The USB-C ports do not support video output.
  • What You Get: Anker 332 USB-C Hub (5-in-1), welcome guide, our worry-free 18-month warranty, and friendly customer service.

What should a CI health check assert?

Assert a successful crawl, a nonempty screenshot string, and the expected viewport dimensions, and retain the exact error message on failure.

Frequently Asked Questions

Does an empty screenshot string prove the target page was empty?

No. It can also mean capture was disabled, the page was not ready, or the browser failed before encoding. Compare result.success, error_message, and a static control URL.

Should headless mode stay disabled in production?

No. Use headless=False while diagnosing so launch and rendering are visible, then return to headless operation once the baseline is stable.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Why can a valid image still be the wrong content?

The server may have returned a bot-check, login page, or other altered response. Inspect the final URL and HTML; this is an access problem rather than a screenshot-encoding problem.

What is the safest way to handle an infinite-scroll page?

Use viewport capture or a bounded number of scroll steps. A page that keeps appending content has no reliable full-page endpoint.

What should a CI health check assert?

Assert a successful crawl, a nonempty screenshot string, and the expected viewport dimensions, and retain the exact error message on failure.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.