TimeoutException in Selenium: Causes and Fixes

11 min readupdated September 10, 2026

Your test fails and the message is almost empty:

selenium.common.exceptions.TimeoutException: Message:

No element name. No line of explanation. Just a timeout.

The instinct is to raise the number and move on. Resist it. A TimeoutException does not mean the page was slow. It means the condition you waited for never became true. Those are different problems, and only one of them is fixed by waiting longer.

What the error actually says

WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("toast")));

Read that as a question: "is an element with id toast visible yet?" Selenium asks it repeatedly, roughly twice a second, for ten seconds. If the answer is still no at the end, you get a TimeoutException.

So the error tells you one thing: that question never got a yes. Your job is to work out which part of the question was wrong.

There are five real reasons. In rough order of how often they turn out to be the cause.

Cause 1: The locator is wrong

This is the most common by a distance, and it is the one people check last.

If the selector does not match anything, the condition can never be true, and you will wait the full ten seconds to be told nothing. The timeout is a symptom. The locator is the bug.

How to tell. Open the page yourself, open devtools, and run the selector in the console:

document.querySelectorAll('[data-testid="toast"]')   // CSS
$x('//div[@class="toast"]')                          // XPath, Chrome devtools

Empty result means you found your problem, and no timeout value will fix it.

Watch for the usual causes: a class that changed with a redesign, a typo, a dynamic id like input-4f3a that is different on every load, or a selector copied from "Copy XPath" that encodes the whole page structure.

This overlaps heavily with NoSuchElementException. The difference is only which call you made. findElement throws NoSuchElement immediately. wait.until keeps asking and eventually throws TimeoutException.

Cause 2: You waited for the wrong condition

The element is there. The condition you chose is not the one you meant.

presenceOfElementLocated only asks whether the element is in the DOM. An element can be in the DOM and invisible, behind an overlay, or disabled. So this passes and the next line fails:

wait.until(ExpectedConditions.presenceOfElementLocated(By.id("submit")));
driver.findElement(By.id("submit")).click(); // ElementNotInteractableException

The reverse is just as common. You wait for visibility on an element that is deliberately hidden until later, and time out even though the app is behaving correctly.

Pick the condition that matches what you are about to do:

You are about to... Wait for
Read text or an attribute presenceOfElementLocated
See it on screen visibilityOfElementLocated
Click it elementToBeClickable
Check it went away invisibilityOfElementLocated
Check the text changed textToBePresentInElement
Confirm navigation urlContains or titleIs

If a click still fails after elementToBeClickable, something is covering it. That is ElementClickIntercepted.

Cause 3: You are looking in the wrong document

The element is on the screen. Selenium genuinely cannot see it.

Two situations cause this, and both are invisible in a screenshot:

It is inside an iframe. An iframe is a separate document. Until you switch into it, Selenium is searching the outer page:

driver.switchTo().frame(driver.findElement(By.cssSelector("iframe#payment")));
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("card-number")));
driver.switchTo().defaultContent(); // remember to come back out

Handling iframes covers this properly.

It is in a new tab or window. Selenium stays on the tab it started on until you tell it otherwise:

for (String handle : driver.getWindowHandles()) {
  driver.switchTo().window(handle);
}

If a timeout appears right after a click that opened something, check this before anything else.

Cause 4: The application really is slow, or broken

Sometimes the boring answer is right. The request took twelve seconds, or it failed and the element genuinely never arrived.

How to tell the difference, and this is the step most people skip: open the browser's network tab and console on the page under test.

  • A pending request that never resolves means a backend problem, not a test problem.
  • A 500 response means you found a real bug. Your test did its job.
  • A JavaScript error in the console can stop rendering entirely, so the element never appears.

This is the case where raising the timeout is legitimate, and even then only after you have confirmed the request completes and the app is healthy.

Cause 5: Implicit and explicit waits are fighting

This one is genuinely confusing, because the timeout you get is not the timeout you set.

If you have set an implicit wait and you use WebDriverWait, both are polling. The implicit wait makes every internal findElement call inside the explicit wait block for its own duration. The two compound, and you get waits far longer than either number, in ways that differ by driver version.

driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10)); // do not mix
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(5));

Pick one strategy. Use explicit waits, and set the implicit wait to zero. Explicit waits can express every condition in the table above. Implicit waits can only ask whether an element exists.

How to debug one in five minutes

  1. Run the selector in the browser console. If it matches nothing, stop. You have found it.
  2. Check the condition matches the action. Are you about to click something you only waited to exist?
  3. Ask whether it is in a frame or another tab. A click just before the failure is the clue.
  4. Open the network tab and console. Confirm the app is healthy before blaming the test.
  5. Only then, consider the duration. And if you raise it, write down why.

Make the failure tell you something

The default message is empty, which is why this error wastes so much time. Give it a message:

WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
wait.withMessage("Toast never became visible after saving the contact");
WebDriverWait(driver, 10).until(
    EC.visibility_of_element_located((By.ID, "toast")),
    "Toast never became visible after saving the contact",
)

Six months from now, on a build server, at the end of a Friday, that sentence is worth more than the stack trace. I have lost an hour to a bare TimeoutException in a suite of two hundred tests, and the fix afterwards took four minutes.

What not to do

Do not just raise the number. If ten seconds was not enough and thirty is, you have not fixed anything. You have made the failure rarer and the suite slower, and it will come back on a busy build agent.

Do not replace it with a sleep.

Thread.sleep(5000); // no

A sleep waits the full time even when the page is ready, and still fails when it is slower than your guess. It is the single biggest cause of slow, flaky Selenium suites. Fixing flaky tests goes through why.

Do not catch and ignore it. A swallowed TimeoutException turns a failing test into a passing one that checks nothing. That is worse than no test, because it reports safety you do not have.

Quick reference

Symptom Likely cause First check
Times out every run, on every machine Wrong locator Run the selector in devtools
Wait passes, next line throws Wrong condition Match the condition to the action
Times out right after a click New tab or iframe Check window handles and frames
Only fails in CI Slow environment or viewport Network tab, and set the window size
Waits far longer than the number you set Mixed implicit and explicit Set implicit to zero
Fails randomly, passes on retry Race condition Wait for the condition, not a duration

Remember this

TimeoutException means your condition never came true. It is a message about the question you asked, not about how fast the page was.

Check the locator first, because it is wrong more often than anything else. Match the condition to the action you are about to take. Never mix implicit and explicit waits. And always give the wait a message, so the next failure explains itself.

The official reference is the Selenium waits documentation.

now prove it

Replace the fixed sleep

Reading is the easy part. Write the test yourself, then we break the app on purpose to check it would really catch the bug.

Solve this problem →

Learn this in full

Reading about a problem is not the same as fixing one. Pick a lecture or a practice problem and write the test yourself.

Keep reading