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

Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.

Start by identifying which layer failed: the WebDriver session or window, page synchronization, screenshot support in the browser driver, or writing the returned image to disk. Selenium’s ScreenshotException means capture was impossible, not that it identifies the cause. Record the exception class and message, binding and version, browser and driver versions, operating system, capture method, and whether the result is missing, empty, or from the wrong tab. Then use the checks below in that order.

1. Record the failure before changing code

A useful report distinguishes a browser-capture error from a filesystem error. Save these facts from the failing run:

  • Language binding and Selenium version.
  • Browser name and version, driver name and version, and operating system.
  • The exact method, such as Python save_screenshot, Java getScreenshotAs, C# GetScreenshot, Ruby save_screenshot, or JavaScript takeScreenshot.
  • Full exception type and message, including the stack trace.
  • Whether the browser session starts, whether the tab is still open, and whether the file is absent, zero bytes, corrupt, or simply saved somewhere unexpected.

Selenium’s own troubleshooting guidance notes that many reported errors originate in the underlying driver. Treat the message as a clue about the failing layer rather than as a diagnosis.

Free tools Windows power users keep installed

One-click scans. No signup required.

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

2. Verify the session, window, and frame

Screenshot commands operate on the current WebDriver context. A closed browser, closed tab, or previously called quit() leaves no valid page to capture.

Check that the session is alive

Run a harmless command immediately before capture, such as reading the current URL or title. If that command raises an invalid-session or “no such window” error, recreate the driver and move the screenshot earlier in the test. Do not catch the exception and continue as though an image was produced.

Select the intended tab

After a link opens a new window, switch to its handle before taking the shot. If a test closes the active tab, switch to one of the remaining handles or stop the test with a clear error. A screenshot of the wrong tab is a context bug even when the PNG is valid.

Restore the correct frame

An iframe affects element lookup and interactions. Switch into the frame only when locating content inside it, and switch back to the default content before a full-page operation if your binding or driver behaves unexpectedly. For an element screenshot, ensure the element belongs to the current document and has not been replaced.

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

Watch for stale element references

A stale element is a reference to a DOM node that no longer exists in the current document. If your workflow locates an element, waits through a navigation or redraw, and then captures that element, locate it again after the page reaches the required state. Full-window capture and element capture can therefore fail for different reasons.

3. Fix synchronization before blaming screenshots

Selenium states that poor synchronization is its most common Selenium-related error. A screenshot taken immediately after navigation, a click, an AJAX update, or a route change may occur while the document is still changing.

Use an explicit wait for the state you need

Wait for a meaningful condition rather than adding an arbitrary long sleep. Examples include the target element becoming visible, a loading mask disappearing, a URL changing, or a known status element containing the expected text. Keep the wait close to the action that triggers the change.

Wait for lazy content before a full-page shot

For pages that load images or sections as you scroll, wait until the relevant content is present and, where necessary, scroll through the page before capture. A successful command can still produce an incomplete image if the page was not ready.

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

Make asynchronous state observable

Have the application expose a reliable readiness marker, such as a completed network request reflected in the DOM. Avoid relying solely on a fixed delay: it may be too short on a slow run and wasteful on a fast one.

4. Use the binding’s documented screenshot API

The exact call and output target differ by language. The WebDriver screenshot endpoint returns Base64-encoded image data, while bindings provide convenience methods that decode or write it.

Python

save_screenshot(filename) saves a PNG and returns False on an IOError. Use a full writable path ending in .png, and check the return value:

from pathlib import Path
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait

out = Path("artifacts/home.png").resolve()
out.parent.mkdir(parents=True, exist_ok=True)
driver = webdriver.Chrome()
try:
    driver.get("https://example.com")
    WebDriverWait(driver, 15).until(lambda d: d.title != "")
    ok = driver.save_screenshot(str(out))
    if not ok or not out.exists() or out.stat().st_size == 0:
        raise RuntimeError(f"Screenshot was not written: {out}")
finally:
    driver.quit()

If this reports failure, inspect the absolute path, directory existence, and process permissions independently of browser capture.

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

Java

Java uses TakesScreenshot.getScreenshotAs with an output target:

File image = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
Files.copy(image.toPath(), Path.of("artifacts/home.png"), StandardCopyOption.REPLACE_EXISTING);

The API documents WebDriverException for failures and UnsupportedOperationException when capture is unsupported. A W3C-conformant implementation follows the WebDriver specification.

C#

var screenshot = ((ITakesScreenshot)driver).GetScreenshot();
screenshot.SaveAsFile(Path.GetFullPath("artifacts/home.png"));

Ruby

driver.save_screenshot(File.expand_path("artifacts/home.png"))

JavaScript

const image = await driver.takeScreenshot();
require('fs').writeFileSync('artifacts/home.png', image, 'base64');

Keep the exception and returned value in your logs. Do not replace a failed capture with an empty file that makes later test steps look successful.

5. Separate capture failure from file-output failure

Test these operations independently:

  1. Capture to the binding’s in-memory or temporary-file result.
  2. Log the result type, byte count (where available), and exception.
  3. Resolve the destination to an absolute path and create its parent directory.
  4. Check that the test process can write there and that the file extension matches the format.
  5. Open the resulting file with an image tool or inspect its byte count to detect a zero-byte or truncated write.

In Python, a False return from save_screenshot specifically indicates an I/O failure. A valid return with no file usually means your path, working directory, permissions, or later cleanup step is wrong.

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

6. Check browser and driver support

If the session is valid, the page is synchronized, and output handling is correct, test the same command with another supported browser/driver combination. Selenium recommends trying multiple browsers to help distinguish a driver defect from test code. A failure that follows one driver points toward that implementation, its version, or environment restrictions.

Interpret startup errors correctly

SessionNotCreatedException commonly indicates a browser/driver version mismatch, a missing or inaccessible driver binary, a non-executable binary, or system restrictions. It is a session-startup clue, not proof of a screenshot-specific defect; fix startup first.

Interpret unsupported-operation errors

Java documents UnsupportedOperationException when screenshot capture is not supported. Confirm the driver implements the screenshot command before changing page code. If one browser supports the command and another does not, retain the working combination or use a separate capture service.

7. Diagnose by symptom

Symptom Likely layer Next check
Invalid session or no such window Session or window context Check for quit(), closed tabs, and window handles.
Stale element before element capture DOM timing or context Wait for the redraw, then locate the element again.
Exception immediately after navigation Synchronization Wait for a specific ready condition.
Unsupported operation Driver capability Check the binding contract and try another supported browser.
Python returns False Filesystem I/O Use an absolute .png path, create the directory, and verify permissions.
Image exists but is blank or incomplete Page state or rendering Wait for content, lazy-load images, and confirm the active tab.
Only one environment fails Driver or host restrictions Compare versions, binary permissions, headless settings, and writable paths.

8. A repeatable recovery workflow

  1. Preserve the exact exception, versions, URL, context, and destination path.
  2. Run a title or URL command to prove the session and active window are usable.
  3. Switch to the intended window and frame; reacquire elements after DOM changes.
  4. Replace sleeps with an explicit wait for the page state required by the image.
  5. Capture using the documented method for your binding and retain its return value or exception.
  6. Write to an absolute, writable path and verify existence and non-zero size.
  7. Repeat in a second supported browser/driver combination.
  8. Reduce the test to a minimal page and script. If the reduced case still fails, report it through Selenium’s support or bug-reporting channels with the minimal reproduction and all version details.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

9. Reliability and CI considerations

Use deterministic artifact directories per test and include the test name, browser, and timestamp in filenames. Preserve screenshots on failure before teardown, because calling quit() first destroys the session. In parallel runs, avoid sharing one driver or one output filename between workers. Log the current URL, window handle, viewport, and wait condition immediately before capture so a wrong-context image is diagnosable.

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

Headless and headed runs can differ in viewport, fonts, GPU behavior, and timing. Compare them when a failure appears only in CI, but keep the same browser and driver versions while isolating the variable. Do not “fix” a flaky capture by swallowing exceptions; that hides regressions.

Or skip the browser setup

If your goal is a dependable website image rather than a browser test assertion, ScreenshotNeo provides a single HTTP capture request. It accepts consent banners as a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets before the shot; each step can be disabled. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and the response identifies the result with X-Page-Verdict and X-Billed headers.

cURL:

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)
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}`);

See the complete parameter reference in the ScreenshotNeo documentation. It also offers an MCP server for AI agents, including Claude and Cursor, with take_screenshot, get_page_info, and capture_pdf. The Free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000. Create a free ScreenshotNeo account to try it.

FAQ

Why does Selenium say screenshot capture is impossible?

That message identifies a failed capture operation, not its cause. Check the live session, active window, synchronization, driver support, and output path in that order.

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

Can a valid screenshot still be wrong?

Yes. A screenshot from another tab, frame, or pre-render state is a successful file operation but an incorrect test artifact. Log and verify context before capture.

Should I retry the screenshot command?

Retry only after correcting a known timing or transient driver condition. Repeating the same command against a closed session or unwritable path cannot repair the underlying problem.

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.