Selenium Errors and Exceptions

Almost every Selenium failure comes down to a handful of exceptions, and most of them have the same three root causes. This guide helps you identify the error in seconds, understand why it happened, and apply the right fix — with Java code — instead of adding another Thread.sleep().

Paste your error message into the Selenium Exception Lookup tool for an instant explanation, or use the table below.

Advertisement

Find Your Error

Error message contains… What it means Full fix guide
stale element reference: element is not attached to the page document The element was re-rendered and your reference is no longer valid StaleElementReferenceException
no such element: Unable to locate element Selenium searched the current context but found nothing NoSuchElementException
element click intercepted … Other element would receive the click Something is covering or overlapping your element See ElementClickInterceptedException
Expected condition failed: waiting for… The expected wait condition never became true TimeoutException
element not interactable Selenium found the element, but it is hidden, disabled, or has no usable size ElementNotInteractable
This version of ChromeDriver only supports Chrome version X ChromeDriver and the browser versions do not match SessionNotCreatedException
NullPointerException on a @FindBy field PageFactory.initElements() was not called NullPointerException with Selenium PageFactory
NoClassDefFoundError / ClassNotFoundException A class is missing at runtime, or its initialization failed ClassNotFoundException vs NoClassDefFoundError
matches more than one step definition Duplicate Cucumber step definitions exist Ambiguous and Undefined Steps
Passes locally, fails in Jenkins There is likely an environment difference involving headless mode, viewport, timing, or test data CI-Only Selenium Failures

Selenium Exceptions List (Selenium 4)

Every exception below is a real class in Selenium 4.25 (checked in the library itself), and all of them extend WebDriverException. Most live in org.openqa.selenium. Note that ElementNotVisibleException and ElementNotSelectableException, still listed in many older tutorials, no longer exist in Selenium 4 — those situations now throw ElementNotInteractableException.

ExceptionParent classWhat it meansUsual fix
NoSuchElementExceptionNotFoundExceptionNo element matches the locator (yet)Wait for it; check the locator, frame and timing
StaleElementReferenceExceptionWebDriverExceptionThe element was removed or re-rendered after you found itFind it again; store locators, not WebElements
ElementClickInterceptedExceptionElementNotInteractableExceptionAnother element (overlay, spinner, banner) is covering itWait for the overlay to disappear, scroll, or close the banner
ElementNotInteractableExceptionInvalidElementStateExceptionThe element exists but can't be used (hidden, zero size, off-screen)Wait until it's visible/clickable; use the visible element
InvalidElementStateExceptionWebDriverExceptionAction not allowed in its state (e.g. typing into a disabled field)Check enabled/readonly state first
TimeoutExceptionWebDriverExceptionAn explicit wait or page load ran out of timeCheck the condition and timeout; find why the app is slow
NoSuchFrameExceptionNotFoundExceptionThe frame to switch to doesn't existWait for the frame: frameToBeAvailableAndSwitchToIt
NoSuchWindowExceptionNotFoundExceptionThe window/tab was closed or the handle is wrongRe-read getWindowHandles()
NoAlertPresentExceptionNotFoundExceptionYou switched to an alert that isn't thereWait for alertIsPresent()
UnhandledAlertExceptionWebDriverExceptionAn alert is open and blocks other commandsAccept or dismiss the alert first
NoSuchShadowRootExceptionNotFoundExceptionThe element has no shadow rootCheck the host element before getShadowRoot()
InvalidSelectorExceptionWebDriverExceptionThe CSS or XPath syntax is invalid (or XPath returns non-elements)Fix the selector; test it in DevTools first
InvalidArgumentExceptionWebDriverExceptionBad argument, e.g. a URL without http://, or a file path that doesn't existCheck the value you pass
JavascriptExceptionWebDriverExceptionThe script run with JavascriptExecutor threw an errorFix the script; check the browser console
ScriptTimeoutExceptionTimeoutExceptionAn async script didn't finish in timeRaise scriptTimeout or fix the script
SessionNotCreatedExceptionWebDriverExceptionThe browser couldn't start (driver/browser version mismatch, bad options)Update Selenium (Selenium Manager matches drivers); check options
NoSuchSessionExceptionWebDriverExceptionCommand sent after quit() or after the browser crashedDon't reuse a quit driver; one driver per test
MoveTargetOutOfBoundsExceptionWebDriverExceptionActions moved the mouse outside the viewport (package org.openqa.selenium.interactions)Scroll the element into view first
UnableToSetCookieExceptionWebDriverExceptionThe cookie couldn't be setOpen a page on the cookie's domain first
InvalidCookieDomainExceptionWebDriverExceptionThe cookie's domain doesn't match the current pageNavigate to the right domain before addCookie
UnexpectedTagNameExceptionWebDriverExceptionnew Select(el) on an element that isn't <select> (package support.ui)Use clicks for custom dropdowns

Because they share a parent, you can catch a group at once: catch (NotFoundException e) covers missing elements, frames, windows, alerts and shadow roots; catch (WebDriverException e) covers everything above.

The Selenium Exception Decision Tree

Most Selenium failures can be diagnosed quickly if you ask a few questions in the right order.

1. Did Selenium Find the Element?

  • No → NoSuchElementException → Check the locator, timing, or whether the element is inside an iframe.
  • Yes → Move to the next question.

2. Can Selenium Interact With It?

  • No, it is hidden or disabled → ElementNotInteractableException → Check the element state and wait condition.
  • No, something is covering it → ElementClickInterceptedException → Check for overlays, loaders, modals, or sticky headers.
  • No, the reference is no longer valid → StaleElementReferenceException → Locate the element again.
  • Yes → Move to the next question.

3. Did It Work Locally but Fail in CI?

If the test passes locally but fails in Jenkins or another CI environment, investigate:

  • Headless browser behavior
  • Browser viewport size
  • Different execution speed
  • Environment configuration
  • Missing test data
  • Authentication or session differences
  • Browser and driver versions

See Debugging in CI for a practical approach.

The Four "Can't Find / Can't Use" Selenium Exceptions

Understanding the difference between these exceptions clears up a large amount of Selenium debugging confusion.

Exception Meaning Usual Cause
NoSuchElementException Selenium could not find the element Locator, timing, or iframe
TimeoutException The wait condition never became true Wrong condition, slow application, or application failure
ElementNotInteractableException Selenium found the element but cannot interact with it Element is hidden, disabled, or otherwise unavailable
ElementClickInterceptedException Selenium found the element, but another element is covering it Overlay, modal, loader, sticky header, or overlapping element

The progression itself is useful for diagnosis.

For example, if you fix a NoSuchElementException and then receive an ElementNotInteractableException, that is actually useful progress. You have moved from a locator problem to an element-state problem.

The Three Root Causes Behind Most Selenium Failures

1. Timing

Your automation script may be executing faster than the web application.

For example, Selenium may attempt to click a button immediately after navigation while the application is still loading it.

The solution is generally not to add Thread.sleep().

Instead, use condition-based explicit waits that adapt to different machine speeds and application response times.

You can also try the Selenium Wait Simulator to understand visually how different wait strategies behave.

2. The Wrong Wait Condition

Different Selenium conditions answer different questions.

For example:

presenceOfElementLocated means that Selenium found the element in the DOM. It does not necessarily mean that the element is visible or ready to be clicked.

If you use the wrong condition, the wait can finish while the element is still unusable, resulting in another exception.

You want to… Recommended wait
Read text or assert on an element visibilityOfElementLocated
Click an element elementToBeClickable
Read an attribute presenceOfElementLocated
Wait for a loader to disappear invisibilityOfElementLocated

Choosing the correct condition makes tests more reliable and makes failures easier to understand.

3. Caching WebElements

Storing WebElement objects in Page Objects or collections can create references that become invalid when the DOM changes.

For example:

// ❌ Caches a WebElement reference.
// The reference can become stale after a DOM re-render.
@FindBy(id = "user")
private WebElement user;

A more resilient approach is to store the locator and find the element when it is needed:

// ✅ Store the locator and resolve the element when needed.
private final By user = By.id("user");

This approach reduces problems caused by stale references and can also make Page Objects easier to maintain.

Code Fixes for the Most Common Selenium Exceptions

NoSuchElementException — Wait and Check for Iframes

A NoSuchElementException does not always mean that the locator is incorrect.

The element may be:

  • Not rendered yet
  • Inside an iframe
  • In a different browsing context
  • Loaded after an asynchronous operation

For an element inside an iframe, switch to the iframe first:

WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));

// If the element is inside an iframe, switch first.
wait.until(
    ExpectedConditions.frameToBeAvailableAndSwitchToIt(
        By.id("payment-frame")
    )
);

WebElement cardNumber = wait.until(
    ExpectedConditions.visibilityOfElementLocated(
        By.id("card-number")
    )
);

cardNumber.sendKeys("4111111111111111");

driver.switchTo().defaultContent(); // Return to the main page.

Always remember that Selenium searches within the current browsing context. If an element belongs to an iframe, the driver must be switched into that frame before Selenium can locate it.

StaleElementReferenceException — Locate the Element Again

A StaleElementReferenceException occurs when Selenium has a reference to an element that is no longer attached to the current DOM.

This often happens when:

  • The page is refreshed.
  • A component is re-rendered.
  • An AJAX request replaces an element.
  • A table is dynamically updated.
  • Navigation causes the DOM to change.

Instead of keeping a cached list of elements, locate the elements again when required.

By rows = By.cssSelector("table#orders tbody tr");

int count = driver.findElements(rows).size();

for (int i = 0; i < count; i++) {

    // Re-find the elements on every iteration
    // instead of using a cached list.
    WebElement row = driver.findElements(rows).get(i);

    row.findElement(By.cssSelector(".view")).click();

    driver.navigate().back();
}

The important principle is:

Do not assume that a WebElement reference remains valid after the DOM changes.

ElementClickInterceptedException — Wait for the Overlay to Disappear

An ElementClickInterceptedException usually means Selenium found the target element, but another element is currently positioned above it.

Common causes include:

  • Loading overlays
  • Modals
  • Cookie banners
  • Sticky headers
  • Dropdown menus
  • Animations
  • Other overlapping elements

A condition-based wait can solve many of these situations:

WebDriverWait wait = new WebDriverWait(
    driver,
    Duration.ofSeconds(10)
);

wait.until(
    ExpectedConditions.invisibilityOfElementLocated(
        By.cssSelector(".loading-overlay")
    )
);

wait.until(
    ExpectedConditions.elementToBeClickable(
        By.id("submit")
    )
).click();

If a sticky header is covering the element, you can scroll it into the center of the viewport:

WebElement element = driver.findElement(By.id("submit"));

((JavascriptExecutor) driver).executeScript(
    "arguments[0].scrollIntoView({block: 'center'});",
    element
);

However, JavaScript should not be used as a shortcut to bypass a genuine user-facing problem. First determine why the element cannot be clicked normally.

SessionNotCreatedException — Let Selenium Manage the Driver

A common SessionNotCreatedException occurs when the browser and driver versions are incompatible.

For example, you may see an error indicating:

This version of ChromeDriver only supports Chrome version X

Since Selenium 4.6, Selenium Manager can automatically manage browser drivers in many common setups.

If your project still contains hard-coded driver paths such as:

System.setProperty(
    "webdriver.chrome.driver",
    "path/to/chromedriver"
);

consider updating your Selenium setup and allowing Selenium Manager to handle driver management where appropriate.

For version-mismatch troubleshooting, see SessionNotCreatedException and ChromeDriver Version Mismatch.

The 60-Second Selenium Diagnosis

Before changing your automation code, use the browser's DevTools to determine whether the element actually exists.

Open DevTools → Console and run:

document.querySelectorAll("#your-locator").length

The result provides a quick diagnostic signal.

Result Meaning
0 The element is not currently in the DOM. Check the locator, timing, or rendering.
1 The element exists. Investigate timing, visibility, state, or browsing context such as an iframe.
2+ Multiple elements match the selector. One or more may be hidden or may not be the intended target.

You can also check whether the page contains iframes:

document.querySelectorAll("iframe").length

If the result is greater than 0, investigate whether the target element is inside an iframe.

This quick check can save significant debugging time.

For additional locator practice, try the CSS & XPath Selector Playground.

Debugging Selenium Failures in CI

When Selenium runs in CI, you often cannot see the browser. That means your test needs to collect enough diagnostic information to explain what happened.

Set a Realistic Headless Viewport

Headless browser execution can behave differently from a normal local browser session.

Set an explicit window size:

ChromeOptions options = new ChromeOptions();

options.addArguments(
    "--headless=new",
    "--window-size=1920,1080"
);

WebDriver driver = new ChromeDriver(options);

Using a predictable viewport can help expose differences caused by responsive layouts and elements that move at smaller screen sizes.

Capture Screenshots and Page Source

When a test fails, capture both a screenshot and the page source.

For example, with TestNG:

@AfterMethod
public void captureOnFailure(ITestResult result) throws IOException {

    if (result.getStatus() == ITestResult.FAILURE) {

        String name =
            result.getMethod().getMethodName()
            + "_"
            + System.currentTimeMillis();

        Path dir = Paths.get("target", "failures");

        Files.createDirectories(dir);

        File shot =
            ((TakesScreenshot) driver)
                .getScreenshotAs(OutputType.FILE);

        Files.copy(
            shot.toPath(),
            dir.resolve(name + ".png")
        );

        Files.writeString(
            dir.resolve(name + ".html"),
            driver.getPageSource()
        );
    }
}

The page source can be particularly useful for locator-related failures.

A screenshot tells you what the browser visually displayed, while the page source can show whether the expected element existed in the DOM and what its actual structure was at the time of failure.

In Jenkins, archive the target/failures directory as a build artifact so the diagnostic files remain available after the test execution finishes.

Selenium Errors That May Actually Be Application Bugs

Not every Selenium exception means the test is wrong.

Before changing the automation, ask whether the failure represents something a real user would also experience.

Symptom What it may actually mean
ElementClickInterceptedException caused by a modal A real user may also be unable to click the underlying element
ElementNotInteractableException with isEnabled() returning false Application validation may be correctly preventing the action
Element disappears after a user action The application behavior itself may be incorrect

For example, using JavaScript to click an element can bypass an overlay.

The automation may then pass even though a real user cannot click the button.

Always ask:

Could a real user perform this action successfully?

If the answer is no, investigate whether the problem is actually an application defect rather than simply modifying the test to force it to pass.

Should You Just Add Retries?

Retry mechanisms such as TestNG's IRetryAnalyzer can sometimes keep a pipeline moving when transient failures occur.

However, retries can also hide flaky tests.

For example:

Test fails → Retry → Test passes

The pipeline may appear green, but the underlying problem still exists.

Use retries carefully and treat them as a temporary mitigation rather than a replacement for root-cause analysis.

When retries are used:

  • Log every retry.
  • Track the frequency of retries.
  • Investigate recurring failures.
  • Fix timing and synchronization problems.
  • Avoid allowing retries to hide persistent defects.

For more practical examples, see Automation Decisions & Flaky Tests.

From Real Projects

Across my 4+ years in testing I've written and maintained Selenium WebDriver scripts in Java with TestNG on Canolog, an automotive dealership management system, and on Testsigma, a low-code test automation platform. Most of the exceptions on this page showed up for me when we moved from running tests one by one to batch, group, parallel and cross-browser runs on Chrome and Firefox: a locator or wait that was fine in a single run started failing when timing changed. What helped most was keeping every locator inside POM classes, so a fix happened in one place, and reviewing each other's scripts before they joined the regression suite.

📚 Official documentation: Selenium docs: Understanding common errors · Selenium docs: Waiting strategies

Exception Handling in Selenium: try-catch the Right Way

Every Selenium exception extends WebDriverException, which is a RuntimeException. That's why the compiler never forces you to catch them. It also means catching them is a choice you should make carefully.

  • Don't catch to hide a failure. An empty catch turns a real bug into a passing test.
  • Use findElements for "is it there?" checks instead of catching NoSuchElementException.
  • Use explicit waits for timing problems, so you rarely need a catch at all.
  • Retry once, narrowly, only for exceptions that a fresh lookup can fix, such as StaleElementReferenceException.
  • When you do catch, add context and rethrow: take a screenshot, log the locator and URL, then let the test fail.
// Presence check without try-catch
public boolean isPresent(By locator) {
    return !driver.findElements(locator).isEmpty();
}

// Narrow retry for a stale element
public void clickWithRetry(By locator) {
    for (int attempt = 1; attempt <= 2; attempt++) {
        try {
            wait.until(ExpectedConditions.elementToBeClickable(locator)).click();
            return;
        } catch (StaleElementReferenceException e) {
            if (attempt == 2) throw e;   // still stale: let the test fail
        }
    }
}

Frequently Asked Questions

What are the most common Selenium exceptions?

Some of the most common Selenium exceptions include:

  • NoSuchElementException
  • StaleElementReferenceException
  • ElementClickInterceptedException
  • TimeoutException
  • ElementNotInteractableException
  • SessionNotCreatedException

Each exception points toward a different category of problem, so identifying the exact exception is an important first step in debugging.

What causes most Selenium failures?

Many Selenium failures can be traced to three recurring areas:

  1. Timing — the automation runs before the application is ready.
  2. Incorrect wait conditions — the test waits for the wrong state.
  3. Cached WebElement references — the DOM changes after Selenium stores the element reference.

Understanding these patterns can make Selenium debugging much faster.

How do I stop Selenium tests from being flaky?

Start by replacing arbitrary sleeps with condition-based explicit waits.

Also:

  • Use reliable locators.
  • Store By locators rather than unnecessary cached WebElement references.
  • Keep test data independent.
  • Use appropriate wait conditions.
  • Control browser viewport size in CI.
  • Capture screenshots and page source on failure.
  • Investigate recurring failures instead of relying heavily on retries.

Why do Selenium tests fail only in Jenkins?

A test can pass locally and fail in Jenkins because the execution environment is different.

Common causes include:

  • Headless browser execution
  • Different viewport size
  • Different browser or driver version
  • Slower CI infrastructure
  • Missing cookies or local storage
  • Missing test data
  • Different environment configuration
  • Timing differences

Start by setting an explicit browser window size such as:

--window-size=1920,1080

Then compare the page source and screenshots from the CI failure with the local execution.

For more information, see Selenium Tests Passing Locally but Failing in Jenkins.

Should I use a JavaScript click to fix intercepted clicks?

Usually, no.

A JavaScript click can bypass the normal browser interaction model and may cause the test to pass even though a real user cannot click the element.

First investigate:

  • Overlay
  • Modal
  • Loader
  • Sticky header
  • Animation
  • Incorrect element state

If a real user cannot perform the action, the problem may be an application defect rather than a Selenium issue.

What is the difference between NoSuchElementException and TimeoutException?

NoSuchElementException is typically thrown when Selenium cannot find an element using findElement() within the applicable implicit wait.

TimeoutException is thrown when an explicit wait such as WebDriverWait reaches its timeout while the expected condition remains false.

For example:

driver.findElement(By.id("login"));

may result in NoSuchElementException when the element cannot be found.

Whereas:

wait.until(
    ExpectedConditions.visibilityOfElementLocated(
        By.id("login")
    )
);

may result in TimeoutException if the element does not become visible before the timeout expires.

Should I mix implicit and explicit waits?

It is generally better to avoid mixing implicit and explicit waits because their interactions can make wait behavior harder to predict.

A common approach is to keep the implicit wait at zero and use explicit waits for specific conditions.

For a detailed comparison, see Implicit vs Explicit vs Fluent Wait.

Are Selenium exceptions checked or unchecked?

Unchecked. They all extend WebDriverException, which extends RuntimeException, so Java doesn't require a try-catch or a throws clause.

What is the parent class of all Selenium exceptions?

org.openqa.selenium.WebDriverException. Catching it catches every Selenium exception, which is why you should catch the specific one you expect instead.

How do you handle exceptions in Selenium WebDriver?

Prevent most of them with stable locators and explicit waits, check optional elements with findElements, retry once only for stale elements, and when you catch an exception, log details and a screenshot and rethrow it so the test still fails.