Selenium Screenshot Not Working in ChromeDriver on Windows: Fix Common Errors
Diagnose Selenium screenshot failures on Windows by checking the API, file path, browser session, element state, ChromeDriver setup, and crash logs.
If a Selenium screenshot is not working in ChromeDriver on Windows, first identify which part failed: the screenshot command raised an exception, the image was saved somewhere unexpected, the image is blank or wrong, or ChromeDriver crashed. These symptoms have different causes; there is no single Windows-only fix. Check the screenshot API, output path, current browser context, target element, and driver setup in that order. Record your Selenium, Chrome, and ChromeDriver versions before changing versions.
1. Classify the failure before changing anything
Write down the exact command, complete exception and stack trace, expected output path, current working directory, active tab and frame, and the versions of Selenium, Chrome, and ChromeDriver. Then classify the symptom:
- Exception from the screenshot call: investigate session state, browsing context, target element, and any remote-debugging attachment.
- Call reports success, but the file is missing: check the resolved path and whether your code actually wrote the returned bytes.
- File exists but is blank, clipped, or unexpected: check the active tab, page readiness, frame, locator, visibility, and element bounds.
- ChromeDriver exits or crashes: distinguish a driver process crash from Chrome closing or a failed file write; preserve logs and make a minimal reproduction.
A screenshot captures the current browsing context. A screenshot command cannot capture the tab you intended if WebDriver is on another window, or recover a session that has already ended. Selenium documents browser and element screenshot operations separately in its windows and tabs guide.
2. Use the screenshot API for the result you want
For a full screenshot of the current page, use the driver screenshot method. For a screenshot of one element, locate that element and call its screenshot method. The following Python example uses Selenium’s documented methods and writes files in the process’s current working directory.
from pathlib import Path
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
output_dir = Path("screenshots")
output_dir.mkdir(parents=True, exist_ok=True)
options = webdriver.ChromeOptions()
driver = webdriver.Chrome(options=options)
try:
driver.get("https://example.com")
wait = WebDriverWait(driver, 20)
wait.until(EC.presence_of_element_located((By.TAG_NAME, "body")))
page_path = output_dir / "page.png"
if not driver.save_screenshot(str(page_path)):
raise RuntimeError("WebDriver did not save the page screenshot")
print(f"Page screenshot: {page_path.resolve()}")
heading = wait.until(EC.visibility_of_element_located((By.TAG_NAME, "h1")))
element_path = output_dir / "heading.png"
if not heading.screenshot(str(element_path)):
raise RuntimeError("WebDriver did not save the element screenshot")
print(f"Element screenshot: {element_path.resolve()}")
finally:
driver.quit()
The API names differ among Selenium language bindings. Use the matching binding’s official documentation rather than translating Python method names literally. At the WebDriver protocol level, a screenshot is returned as Base64-encoded PNG data; a language binding may decode and save it for you. See the Selenium JavaScript WebDriver API.
Check where the file is written
A relative path such as page.png is relative to the process working directory, which can differ between a terminal, IDE, scheduled task, service, and test runner. Print the absolute path, create the parent directory, and check the return value. If you use the WebDriver screenshot bytes API directly, write those bytes to the intended path and check for filesystem errors separately from capture.
3. Check the live session, tab, and frame
Before retrying, verify that the driver still has a live session and is controlling the intended window. Inspect the window handles and switch explicitly when your test opened multiple tabs:
handles = driver.window_handles
print("Window handles:", handles)
# Switch to the intended handle if needed:
driver.switch_to.window(handles[-1])
print("Current URL:", driver.current_url)
Do not use a driver after driver.quit(). Also inspect code that calls driver.close(): closing the last open tab can end the session. Selenium lists a deleted session as a common cause of InvalidSessionIdException. After navigation or switching frames, reacquire elements; references found in an earlier document may no longer be valid. See Selenium’s common errors guide.
If the intended content is inside an iframe, switch into that frame before locating its elements. Switch back to the top-level document when needed:
frame = WebDriverWait(driver, 20).until(
EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR, "iframe"))
)
# Locate and use elements inside the frame here.
driver.switch_to.default_content()
4. Make element screenshots wait for the right state
An element screenshot is not the same operation as a page screenshot. Confirm that your locator matches the intended element and that it is visible in the current page state. Waiting for an element to exist is not always enough: for capture, wait for visibility, and when the page has asynchronous content, wait for the specific content or application state your image needs.
target = WebDriverWait(driver, 20).until(
EC.visibility_of_element_located((By.CSS_SELECTOR, "main .report-card"))
)
driver.execute_script(
"arguments[0].scrollIntoView({block: 'center'});", target
)
target.screenshot("report-card.png")
Check that the selector is unique and that the element is not hidden by responsive layout, a closed dialog, or a loading state. If an element screenshot raises an error or remains clipped, preserve a small reproducible page and the exact browser and driver versions; scrolling is a useful check, not a guaranteed fix for every rendering issue. Selenium recommends explicit waits for timing-sensitive states in its troubleshooting documentation.
5. Verify ChromeDriver discovery and version information
ChromeDriver is a separate executable used to control Chrome. On Windows, confirm that Chrome is installed in a recognized location and that the driver executable can be found and launched. Selenium’s driver management guidance and Unable to Locate Driver Error guide explain driver discovery; Chrome’s ChromeDriver setup guide describes making the executable available through PATH or configuring its location.
- Record the installed Selenium version from your environment, not a different system Python or package environment.
- Record the Chrome version and the ChromeDriver executable path and version actually used by the process.
- Check that the executable exists, is accessible to the account running the script, and can be launched.
- Consult current official ChromeDriver download and compatibility guidance for your version tuple. Avoid applying old version-pair advice without checking the versions in your environment.
An Unable to locate driver error is a driver-discovery problem, not a screenshot-file problem. Fix discovery first, then reproduce the capture failure.
6. Treat remote-debugging attachment as a special case
If ChromeDriver attaches to an already running Chrome process using debuggerAddress, some WebDriver commands can be unsupported because ChromeDriver’s automation extension is loaded when ChromeDriver launches a new session. This is relevant when the configuration and error point to an unsupported operation; it is not a general fix for blank images or missing files.
When that limitation matches, retry by letting ChromeDriver start a fresh Chrome session and remove the debuggerAddress attachment. Chrome documents this behavior and remedy in Operation not supported when using remote debugging.
7. If ChromeDriver crashes, preserve a minimal reproduction
A ChromeDriver crash is different from Chrome closing, a WebDriver command failing, or a screenshot not being written. Reduce the script to driver startup, one navigation, one screenshot call, and shutdown. Keep the full logs, exact versions, and steps that reproduce the failure. Chrome’s ChromeDriver crashes guide describes crash investigation; its Windows dump-analysis workflow is advanced and intended for contributor-level debugging. Historical entries in the ChromeDriver release history mention element screenshot fixes, but historical fixes do not establish that a current Windows release has a general screenshot defect.
8. Common errors and what to check
| Symptom or error | Likely area to inspect | Next step |
|---|---|---|
InvalidSessionIdException |
Session ended, driver quit, or last tab closed | Create a fresh session or switch to a valid window handle; inspect close() and quit() calls. |
Unable to locate driver |
ChromeDriver executable is missing, inaccessible, or not discoverable | Check executable path, permissions, PATH, and the Selenium driver setup guidance. |
| Element not visible or not interactable | Wrong locator, hidden element, or page state not ready | Wait for visibility, verify the selector and current context, then scroll into view if appropriate. |
| Unsupported operation after attaching to Chrome | Existing Chrome session attached with debuggerAddress |
When the error matches this limitation, retry with a Chrome session launched by ChromeDriver. |
| Screenshot call succeeds but expected file is absent | Relative path or file-writing step | Print the absolute path, check the working directory, create the directory, and inspect the write result. |
| Image is blank or unexpected | Wrong tab/frame, page not ready, or target not visible | Print the current URL, verify the window and frame, and wait for the actual content state before capture. |
| ChromeDriver process exits | Driver crash or process/environment failure | Separate it from Chrome closing; reduce to a minimal reproduction and retain logs and versions. |
These are diagnostic starting points, not interchangeable diagnoses. Use the exact exception and setup to choose the next check.
9. Performance, reliability, and cost
For Selenium, screenshot time is part of the whole browser workflow: starting Chrome, loading the page, waiting for the needed state, and encoding or writing the image can all contribute. Keep the browser session alive for multiple captures when your test design permits it, wait for a meaningful page condition instead of an unnecessarily long fixed delay, and avoid capturing before required content is ready. For reliable automation, make the target URL and wait condition deterministic, save to an explicit path, and retain browser and driver logs when a capture fails.
Local Selenium runs require a browser and driver environment you maintain. If the task is simply to obtain a screenshot from a URL and you do not need browser automation in your own process, a screenshot API is an alternative. API usage has a service cost rather than local browser setup cost; compare the plan limits and the expected capture volume before choosing.
10. Or skip the browser setup
ScreenshotNeo is a website screenshot API and MCP server. One GET request returns a PNG, JPEG, WebP, or PDF. The request below saves a WebP screenshot of a page; see the ScreenshotNeo API documentation for the available options.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
ScreenshotNeo accepts cookie and consent banners before capture and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each step can be turned off. Bot checks and CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers identify the page verdict and billing status. Its MCP server provides take_screenshot, get_page_info, and capture_pdf for Claude, Cursor, and other MCP clients. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 screenshots.
Sign up for 1,000 free screenshots a month, with no card required.
FAQ
Does Selenium save screenshots as JPEG by default?
The WebDriver screenshot response is PNG data. If you need another format, convert the image after capture with an image library appropriate to your language.
Can I diagnose this without knowing the ChromeDriver version?
Record it before changing the setup. Driver discovery and compatibility questions depend on the executable actually used, so the version and path are useful evidence.
Will a browser screenshot include content in every tab?
No. A screenshot applies to the current browsing context. Switch to the intended window and frame before capture.


