Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
A WebDriver connection that disappears during a screenshot is usually a symptom, not the root cause. Classify the failure first: a synchronization race, a browser or driver process exit, a page/script timeout, a local file-write error, or a remote transport problem. Then apply the fix for that class. The sequence below isolates each layer without hiding failures behind longer timeouts.
Classify the failure before changing code
Save the complete exception, WebDriver command, URL, session ID and timestamp. The exact wording points to a different layer:
| Symptom | Likely layer | First check |
|---|---|---|
timeout while loading or executing script |
Page or script timing | Configured timeout and an explicit readiness condition |
get_screenshot_as_file() returns False |
Screenshot-file I/O | Absolute path, directory permissions and free disk space |
| Connection reset, disconnected, or session deleted | Browser/driver process or transport | Driver and browser logs; whether the browser process exited |
| Failure only on a grid or remote host | Remote endpoint/network | Compare with a local run and inspect server/network logs |
Do not treat all four as “the screenshot is flaky.” A file permission error does not require a new browser session, while a crashed browser cannot be repaired by changing the output filename.
1. Stabilize the page state with an explicit wait
Selenium identifies poor synchronization as its most common error source. A screenshot command can arrive while a framework is replacing the DOM, an overlay is covering the target, or lazy content is still being inserted. Replace fixed sleeps with a bounded wait for the condition that makes your particular capture valid.
#1 Best Overall
Wait for the element or state you will capture
Examples include the target element becoming visible, a loading overlay becoming invisible, or a known application state appearing. Keep implicit waits disabled when using explicit waits; mixing the two can produce unpredictable timeout behavior.
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException
from pathlib import Path
out = Path("/tmp/shots").resolve()
out.mkdir(parents=True, exist_ok=True)
options = webdriver.ChromeOptions()
# options.add_argument("--headless=new") # enable when appropriate for your environment
driver = webdriver.Chrome(options=options)
driver.implicitly_wait(0)
driver.set_page_load_timeout(45)
driver.set_script_timeout(30)
try:
driver.get("https://example.com/dashboard")
wait = WebDriverWait(driver, 20, poll_frequency=0.2)
wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "main.dashboard")))
wait.until(EC.invisibility_of_element_located((By.CSS_SELECTOR, ".loading-overlay")))
path = out / "dashboard.png"
ok = driver.get_screenshot_as_file(str(path))
if not ok:
raise OSError(f"WebDriver could not write {path}")
finally:
driver.quit()
When the wait expires, log the current URL, the selector/state you were waiting for, browser console output and the driver log. That evidence distinguishes a page that never reached readiness from a browser that vanished.
Why a sleep is not a reliable substitute
A fixed delay is either too short on a busy CI host or unnecessarily long on a fast run. It also says nothing about whether a navigation actually completed. Use a sleep only for a documented animation or debounce interval, and still verify the resulting DOM condition.
Do these 3 things before closing this tab:
1Fix the driver behind crashes, sound loss and screen glitches2Repair Windows errors before they cause bigger problems3Scan for outdated or missing drivers - takes under a minute2. Verify browser, driver and Selenium identity
Record these values for every failing job:
- Browser name, exact version and channel.
- Driver name and exact version.
- Selenium binding version.
- Operating system, architecture and whether the run is local, containerized or remote.
- The executable paths actually selected by the test process.
ChromeDriver is a standalone server implementing WebDriver and WebDriver BiDi. Current Chrome for Testing channels distribute browser and driver binaries. An unexpected executable earlier on PATH, or a browser/driver channel mismatch, can cause the browser to exit while the client is sending a screenshot command.
Turn on verbose logs
Configure Selenium service logging and retain the resulting files as CI artifacts. Look for the browser launch command, the binary path, capability negotiation and the last command before the process exit. If the log shows a new session was never established, investigate startup; if it ends immediately before the screenshot, investigate a crash or resource limit.
Rank #2
Test another supported browser
Run the same minimal reproducer with another installed browser. If only one browser fails, focus on that browser’s binary, profile, flags and driver. If all browsers fail at the same point, the page synchronization, host resources or remote transport is more likely.
3. Reproduce browser startup outside WebDriver
Use the exact browser binary and user identity from the failing test environment. Launch it directly with the same headless/display and container settings, then open the target URL. Preserve stderr and browser logs. This separates a browser startup crash from a WebDriver protocol problem.
The Tool Desk
Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Linux and container checks
- Confirm the test is not running Chrome as
root. ChromeDriver documents root execution on Linux as a common startup-crash cause. - Compare the CI user, sandbox configuration, installed browser path and headless flags with a successful local run.
- Check shared-memory capacity, process and file-descriptor limits, and whether the container is killing the browser for memory.
- Keep the browser and driver logs when a process exits so a crash is not mistaken for a network reset.
The --no-sandbox flag is an unsupported, highly discouraged workaround. Configure a regular, non-privileged user and correct the container instead.
4. Separate timeout errors from screenshot-file errors
Set page-load and script timeouts for the application rather than increasing every timeout after a failure. A slow navigation, a script that never resolves, a browser crash and an unwritable PNG path are different incidents.
Use an absolute, writable destination
Create the directory before the test and check the screenshot API’s return value. In Selenium’s Python API, get_screenshot_as_file() (also exposed as save_screenshot()) returns False for an I/O failure. Ignoring that boolean can make a local file problem look like a lost session.
Rank #3
from pathlib import Path
path = Path("artifacts") / "run-42.png"
path.parent.mkdir(parents=True, exist_ok=True)
path = path.resolve()
if not driver.get_screenshot_as_file(str(path)):
raise RuntimeError(f"Screenshot write failed: {path}")
if not path.is_file() or path.stat().st_size == 0:
raise RuntimeError(f"Screenshot is missing or empty: {path}")
Check directory ownership, read-only mounts, disk quota and available space. A successful WebDriver command followed by a missing file is an I/O diagnosis, not evidence that ChromeDriver disconnected.
PC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware match5. Treat remote execution as a separate layer
WebDriver can control a local browser or a browser on another machine through Selenium Server. A remote run adds endpoint authentication, firewalls, proxies, network latency and server health to the browser and file layers.
Use a local-versus-remote comparison
- Run the minimal test locally with the same URL and wait condition.
- Run it against the remote endpoint with server and network logs enabled.
- Compare command latency, session lifetime, browser process logs and screenshot handling.
- Change one variable at a time: endpoint, browser version, host or wait condition.
If local succeeds and remote fails, inspect endpoint reachability, idle timeouts, proxy resets and server-side browser exits. If both fail, return to synchronization, binary alignment and host resources.
Secure the endpoint
Firewall the WebDriver endpoint, restrict allowed IP addresses, use a protected network and run tests with a non-privileged account. Do not expose an unauthenticated driver service to the public internet. A managed browser grid may reduce maintenance when local infrastructure is the dominant source of failures, but it does not remove the need to diagnose page readiness and file handling.
A repeatable diagnostic sequence
- Save the full exception, command, URL, session ID and timestamp.
- Enable Selenium, driver and browser logs and preserve them with the test artifact.
- Replace sleeps with an explicit wait for the screenshot’s readiness condition; keep implicit waits off.
- Print browser, driver, Selenium, OS, architecture and executable-path details.
- Launch the exact browser binary directly in the same environment.
- Check root execution, sandbox/container restrictions, shared memory and process exits.
- Confirm page-load/script timeout values and an absolute writable PNG path; check the screenshot return value.
- Compare another supported browser and local versus remote execution.
- After classification, change one variable at a time and retain the smallest reproducer that still fails.
Common failure patterns and targeted fixes
“Session deleted” immediately after navigation
Read the driver log for a browser process exit. Verify binary versions, launch the same binary directly, and inspect root/container and memory conditions. Do not add retries until the process remains alive.
Rank #4
“Connection reset” only under load
Compare command latency and host resource usage with a single-worker run. Reduce concurrency temporarily, inspect shared memory and file descriptors, and check whether a remote proxy or server idle limit closes the connection.
Screenshot intermittently captures a blank or half-rendered page
The session may be healthy; the page is not ready. Wait for the target element and for loading overlays or known skeleton states to disappear. Capture the URL and DOM state when the wait times out.
Method reports failure but the session remains usable
Check the boolean result and absolute path, then inspect permissions, mount mode and free disk space. This is a file-write failure unless a subsequent WebDriver command also reports a disconnected session.
Only the remote grid fails
Run locally, then compare endpoint logs, network path, server health and browser lifetime. Protect the endpoint and verify that the remote host uses the intended browser and driver binaries.
Quick wins for a faster PC:
Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Repair Windows errors before they cause bigger problemsFix Now →Or skip the browser setup
For production captures, ScreenshotNeo provides a single HTTP request instead of maintaining Selenium, browser binaries and driver sessions. Cookie and consent banners are accepted and removed before capture, along with 60+ known consent platforms, newsletter popups and chat widgets; each step can be disabled. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads and cache hits cost nothing, and the response identifies the result with X-Page-Verdict and X-Billed headers. Its MCP server lets Claude, Cursor and other MCP clients call take_screenshot, get_page_info and capture_pdf.
The API supports full-page captures with lazy images loaded, CSS-selector element shots, dark mode, 12 device presets or custom viewports, retina scale, PDF paper sizes/margins/landscape/page ranges, HTML/CSS rendering, custom JavaScript and CSS, clicks, selector waits, delays, network-idle waits, request/resource blocking, headers, cookies, user agents, Authorization, timezone, geolocation, transparent backgrounds, resizing, TTL caching, signed image links, asynchronous jobs with signed webhooks, bulk capture of 100 URLs per call, a usage API and an OpenAPI specification. Common parameter names used by other screenshot APIs are accepted to ease migration.
Best Value
cURL
See the ScreenshotNeo documentation for authentication and options.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Python
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
r.raise_for_status()
open("shot.webp", "wb").write(r.content)
Node.js
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`${res.status} ${res.statusText}`);
const fs = await import('node:fs/promises');
await fs.writeFile('shot.webp', Buffer.from(await res.arrayBuffer()));
There is a free allowance of 1,000 screenshots per month with no card. Paid plans start at $5 for 3,000 shots; every feature is on every plan. Create a free ScreenshotNeo account to try the API.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Reliability, performance and cost decisions
- Retries: retry only classified transient failures, such as a remote transport reset. Reusing a dead session will not fix a browser crash; create a new session and preserve the original logs.
- Parallelism: increase workers only after measuring browser memory, shared memory, CPU and file-descriptor limits. More sessions can turn a stable test into repeated process exits.
- Readiness: a precise wait is usually faster than a generous global timeout because it captures as soon as the required state exists.
- Observability: store command timing, session ID, URL, versions, paths, verdicts and logs with each artifact.
- Remote trade-off: remote execution centralizes browsers but adds network and endpoint failure modes; local execution removes transport dependence but leaves binary and host maintenance to you.
Frequently Asked Questions
Should I restart the driver after every screenshot?
No. Keep a session for related captures while it remains healthy. Start a new session only after logs show a browser or driver process exit, or after the session is explicitly invalid.
Can increasing the screenshot timeout fix a disconnected session?
Usually not. A timeout controls waiting for a page or script; a disconnected or deleted session indicates process or transport failure. Classify the exception first.
Why does a screenshot work locally but fail in CI?
CI often changes the user, browser path, sandbox/container settings, shared-memory limits and available resources. Launch the exact CI browser directly and compare its logs and versions with the local run.
Is a blank screenshot proof that WebDriver disconnected?
No. It can mean the page was captured before its content became ready. Wait for a target DOM condition and inspect the session separately from the image file.
Recommended Free Tools
Quick Recap
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.

