Skip to content
QA Knowledge Hub

NoSuchElementException in Selenium

Updated 2026-11-12 · 3 min read

Selenium could not find an element matching your locator at the moment it looked. In practice the cause is almost always one of five things: the locator, timing, an iframe, a different page than you think, or a shadow root.

The message looks like this:

org.openqa.selenium.NoSuchElementException: no such element: Unable to locate element:
{"method":"css selector","selector":"#submit-btn"}

It means: at the instant of the lookup, the current page had no element matching that locator. Work through the causes in this order. It is the order in which they usually turn out to be the answer.

1. The locator is wrong

A typo, an id that changes on every page load (btn-83721), or a copied absolute XPath that broke after a layout change. Check it in the browser: press F12, open the console and run document.querySelector("#submit-btn") or $x("//button[@id='submit-btn']"). If that returns nothing or null, the locator is the problem. Paste the page's HTML into the XPath and CSS tester to try alternatives.

Fixes: use a stable attribute (data-testid, a meaningful id, a label), and write the locator by what the element is, not where it sits in the tree.

2. It is a timing problem

The element exists, but not yet. The page is still loading or a request has not returned.

// Fails: looks immediately
driver.findElement(By.id("result")).getText();

// Works: waits up to 10 seconds for it to be visible
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
String text = wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("result"))).getText();

Do not fix this with Thread.sleep(5000). It makes every run slow and still fails when the system is slower than five seconds.

3. The element is inside an iframe

Selenium looks only at the current frame. If the element is in an iframe, switch into it first.

driver.switchTo().frame(driver.findElement(By.cssSelector("iframe#payment")));
driver.findElement(By.id("card-number")).sendKeys("4111111111111111");
driver.switchTo().defaultContent();   // go back to the main page

Telltale sign: you can see the element in DevTools, but inside a #document node nested in an iframe.

4. You are on a different page, window or tab than you think

A click opened a new tab, a redirect sent you to a login page, or the previous step failed silently. Print driver.getCurrentUrl() and driver.getTitle() and take a screenshot at the failure. For a new window, switch to it with driver.getWindowHandles().

5. It is in a shadow DOM

A normal locator does not reach inside a shadow root. In Selenium 4 you can get the shadow root of the host and search inside it with CSS.

WebElement host = driver.findElement(By.cssSelector("my-widget"));
SearchContext shadow = host.getShadowRoot();
shadow.findElement(By.cssSelector("button.save")).click();

XPath does not work inside a shadow root; use CSS.

6. Less common causes

  • The element is rendered only after a scroll (lazy loading). Scroll to the bottom or to the item, then wait.
  • The element exists only in some conditions (a cookie banner, an A/B variant). Check for presence with findElements(...).
  • The test runs in headless mode or at a smaller window size, so a responsive layout changed the markup. Set the window size explicitly in the test.
  • The locator matches an element in the page source, but it is created by JavaScript after the load event.

How to check for absence without an exception

boolean present = !driver.findElements(By.id("banner")).isEmpty();

findElements returns an empty list instead of throwing.

Checklist

  1. Run the locator in the browser console on the failing page.
  2. Print the URL and take a screenshot at the failure.
  3. Check for iframes and shadow roots.
  4. Replace sleeps with an explicit wait on the right condition.
  5. Rewrite the locator on a stable attribute.

Quick answers

What is the difference between NoSuchElementException and TimeoutException?

NoSuchElementException is thrown by findElement straight away when nothing matches. TimeoutException is thrown by an explicit wait when its condition is still false after the timeout.

Want a project you can show in interviews?

The portfolio project kit walks you through testing a deliberately buggy app with Selenium or Playwright and API tests, then explaining it. The app itself is free.