TimeoutException in Selenium

The Errors

org.openqa.selenium.TimeoutException:
  Expected condition failed: waiting for visibility of element located by By.id: submit
  (tried for 10 second(s) with 500 milliseconds interval)
org.openqa.selenium.ElementNotInteractableException:
  element not interactable

Both mean Selenium found something — it just couldn't proceed. That's the key difference from NoSuchElementException.


TimeoutException

What it means

Your WebDriverWait polled for the full timeout and the condition never became true. Note what the message tells you: the condition it was waiting for, and for how long. Read it — it names your bug.

The Causes

Wrong condition ⭐

The most common by far.

Advertisement
// You waited for PRESENCE (in the DOM), then clicked
wait.until(ExpectedConditions.presenceOfElementLocated(By.id("submit"))).click();

// 💥 element is in the DOM but hidden → passes the wait, fails the click

Presence ≠ visible ≠ clickable. Pick the condition that matches what you're about to do.

Condition Waits for Use before
presenceOfElementLocated In the DOM (may be invisible) Reading attributes only
visibilityOfElementLocated In DOM and visible getText(), assertions
elementToBeClickable Visible and enabled click()

It genuinely takes longer than the timeout

Slow API, heavy page. Raise the timeout — but only after confirming it's not the wrong condition.

Wrong locator

The condition can never pass because nothing matches. TimeoutException is NoSuchElementException wearing a coat: the wait swallowed the "not found" and reported a timeout instead.

Wrong context

It's in an iframe you haven't switched to. Same story: it'll never appear.

The Fixes

// ✅ Match the condition to the action
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
wait.until(ExpectedConditions.elementToBeClickable(By.id("submit"))).click();

// ✅ Wait for the loader to GO, not just the button to appear
wait.until(ExpectedConditions.invisibilityOfElementLocated(By.className("spinner")));

// ✅ Custom condition when built-ins don't fit
wait.until(d -> d.findElement(By.id("count")).getText().equals("5"));

⚠️ Don't mix implicit and explicit waits. Setting both makes timeouts unpredictable — Selenium's own docs warn against it. Pick explicit, set implicit to zero.


ElementNotInteractableException

What it means

Selenium found the element but it isn't in a state you can interact with.

The Causes

Cause Why
Hidden display:none, visibility:hidden, opacity:0
Zero size Width or height is 0
Disabled <button disabled>
Off-screen Outside the viewport (common in headless 800×600)
Not ready yet Rendered but still animating in

The Fixes

// 1. Wait for clickable, not just present ⭐
wait.until(ExpectedConditions.elementToBeClickable(By.id("submit"))).click();

// 2. Scroll it into view
((JavascriptExecutor) driver).executeScript(
    "arguments[0].scrollIntoView({block:'center'});", element);

// 3. Check WHY it's not interactable before forcing it
System.out.println("displayed: " + element.isDisplayed());
System.out.println("enabled:   " + element.isEnabled());
System.out.println("size:      " + element.getSize());

That third one matters. If isEnabled() is false, no amount of waiting helps — the app is telling you the button shouldn't be clicked yet. Usually a form validation you haven't satisfied. That's a real finding, not an automation problem.


Telling the Three Apart ⭐

Exception Selenium… Means
NoSuchElementException couldn't find it Wrong locator, timing, or iframe
TimeoutException Found nothing matching the condition in time Wrong condition, or genuinely slow
ElementNotInteractableException found it, can't use it Hidden, disabled, zero-size, off-screen
ElementClickInterceptedException Found it, something's on top Overlay/popup/sticky header

The progression is diagnostic: if you fix a NoSuchElement and now get ElementNotInteractableException, you've made progress — the element exists, so now it's a state problem, not a locator problem.


The Trap: Longer Timeouts

// ❌ The instinct
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(60));

This turns a 10-second failure into a 60-second failure. It doesn't fix anything — it just makes your suite slower at being wrong.

If a 10-second wait times out, the condition is usually wrong, not slow. Check the condition before you touch the number.


The Interview Answer

"TimeoutException means the wait condition never became true in the timeout — most often because the condition was wrong, like waiting for presence and then clicking, when presence only means it's in the DOM, not visible or enabled. ElementNotInteractableException means Selenium found the element but it's hidden, disabled, zero-size, or off-screen. I match the condition to the action — elementToBeClickable before a click — and I check isDisplayed(), isEnabled(), and getSize() to see why, rather than just increasing the timeout, which only makes the failure slower."


FAQs

Why does my explicit wait time out when the element is right there?

Usually the wrong condition. presenceOfElementLocated passes while the element is still hidden — use visibilityOfElementLocated or elementToBeClickable.

Should I just increase the timeout?

Rarely. If 10 seconds isn't enough, the condition is usually wrong. A longer timeout just makes the failure slower.

What's the difference between TimeoutException and NoSuchElementException?

NoSuchElement = the immediate lookup found nothing.

Timeout = a wait polled and the condition never came true — often the same underlying cause, reported differently.

Why is my element "not interactable" when I can see it?

It may be disabled, zero-size, still animating, or off-screen. Check isDisplayed(), isEnabled(), and getSize().

Can I mix implicit and explicit waits?

No. Mixing them causes unpredictable timeouts. Use explicit waits and leave implicit at zero.