Selenium TimeoutException: Message: (tested)

selenium.common.exceptions.TimeoutException: Message: with nothing after it means a WebDriverWait condition never became true; the message is empty unless you pass message= to until(). Usually the locator is wrong, the element is in an iframe, or you waited for visibility of a hidden element.

Setup used in every block

common.py writes a small HTML page to a local file and starts headless Chrome.

import os, pathlib
from selenium import webdriver
CHROME = os.path.expanduser("~/.cache/ms-playwright/chromium-1248/chrome-linux64/chrome")
def page(html):
    p = pathlib.Path("/tmp/sl383/page.html"); p.write_text(html); return p.as_uri()
def driver():
    o = webdriver.ChromeOptions()
    o.binary_location = CHROME
    o.add_argument("--headless=new"); o.add_argument("--no-sandbox"); o.add_argument("--window-size=1000,700")
    return webdriver.Chrome(options=o)

1. Reproduce it: "TimeoutException: Message:" with nothing after it

from common import *
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException
d = driver()
d.get(page('<input id="q">'))
try:
    WebDriverWait(d, 2).until(EC.presence_of_element_located((By.ID, "#q")))
except TimeoutException as e:
    print(repr(str(e).splitlines()[0]), "+", len(str(e).splitlines()) - 1, "stacktrace lines")
try:
    WebDriverWait(d, 2).until(EC.presence_of_element_located((By.ID, "#q")),
                              message='no element with id "#q" after 2s')
except TimeoutException as e:
    print(repr(str(e).splitlines()[0]), "+", len(str(e).splitlines()) - 1, "stacktrace lines")
print("By.ID 'q':", WebDriverWait(d, 2).until(EC.presence_of_element_located((By.ID, "q"))).tag_name)
print("By.CSS_SELECTOR '#q':", WebDriverWait(d, 2).until(EC.presence_of_element_located((By.CSS_SELECTOR, "#q"))).tag_name)
d.quit()

Output:

'Message: ' + 20 stacktrace lines
'Message: no element with id "#q" after 2s' + 20 stacktrace lines
By.ID 'q': input
By.CSS_SELECTOR '#q': input

WebDriverWait(...).until() raises TimeoutException when its condition never became true within the timeout. By default the message is empty, which is why the error reads just Message: followed by a stacktrace (from chromedriver, not your code). Pass message= to until() so your logs say what you were waiting for.

The cause in this block is the most common one: a wrong locator. By.ID takes the bare id ("q"); "#q" is CSS syntax and only works with By.CSS_SELECTOR. Before raising the timeout, check the locator with len(driver.find_elements(by, value)) on the loaded page.

2. The element is there, but the condition cannot become true

from common import *
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException
d = driver()
d.get(page('<iframe srcdoc="<button id=go>Go</button>"></iframe><p id="msg" style="display:none">saved</p>'))
for name, cond in [("presence of #go (inside iframe)", EC.presence_of_element_located((By.ID, "go"))),
                   ("visibility of #msg (hidden)", EC.visibility_of_element_located((By.ID, "msg"))),
                   ("presence of #msg (hidden)", EC.presence_of_element_located((By.ID, "msg")))]:
    try:
        WebDriverWait(d, 2).until(cond)
        print(name, "-> OK")
    except TimeoutException:
        print(name, "-> TimeoutException")
WebDriverWait(d, 2).until(EC.frame_to_be_available_and_switch_to_it((By.TAG_NAME, "iframe")))
print("after switching into the frame:", WebDriverWait(d, 2).until(EC.element_to_be_clickable((By.ID, "go"))).text)
d.quit()

Output:

presence of #go (inside iframe) -> TimeoutException
visibility of #msg (hidden) -> TimeoutException
presence of #msg (hidden) -> OK
after switching into the frame: Go

Two other frequent causes: the element is inside an <iframe> (the wait searches only the current frame, so switch with EC.frame_to_be_available_and_switch_to_it first), and the wrong condition: visibility_of_element_located times out for an element that exists but is hidden, while presence_of_element_located succeeds for it. Pick the condition that matches what you need next: presence to read it, visibility to read visible text, element_to_be_clickable to click.

3. TimeoutException from driver.get(): page load timeout

import threading, time
from http.server import ThreadingHTTPServer, BaseHTTPRequestHandler
from common import driver
from selenium.common.exceptions import TimeoutException
class Slow(BaseHTTPRequestHandler):
    def do_GET(self):
        time.sleep(5)
        self.send_response(200); self.end_headers(); self.wfile.write(b"<p>slow</p>")
    def log_message(self, *a): pass
srv = ThreadingHTTPServer(("127.0.0.1", 8963), Slow)
threading.Thread(target=srv.serve_forever, daemon=True).start()
d = driver()
d.set_page_load_timeout(2)
t = time.time()
try:
    d.get("http://127.0.0.1:8963/")
except TimeoutException as e:
    print(f"after {time.time() - t:.1f}s:", type(e).__name__ + ":", e.msg.splitlines()[0])
d.quit(); srv.shutdown()

Output:

after 2.0s: TimeoutException: timeout: Timed out receiving message from renderer: -0.002

A different TimeoutException comes from driver.get() itself when the page takes longer than set_page_load_timeout() (the default is 300 seconds). Chromedriver words it as timeout: Timed out receiving message from renderer. Raise the timeout, or, if you only need the DOM and not every image and script, use options.page_load_strategy = "eager", which returns at DOMContentLoaded.

4. Checklist

Related: Selenium element not interactable, Selenium element click intercepted, Selenium StaleElementReferenceException.

Frequently asked questions

Why is the Selenium TimeoutException message empty?

WebDriverWait.until() raises TimeoutException with the message you pass to until(message=...); without one it is empty, so only 'Message:' and a stacktrace are printed.

Why does WebDriverWait time out when the element exists?

Common reasons: the locator is wrong (e.g. By.ID with '#id'), the element is inside an iframe you have not switched to, or you wait for visibility of an element that is hidden.

Written with AI assistance. Measured on 2026-10-23 with Selenium 4.51.0 (Python 3.13.5) and headless Chrome for Testing 156.0.8078.4. Each block was run verbatim and the output pasted unedited. PlainHeaders is our extension; Python, Selenium and Chrome are free.