Selenium "WebDriverException: ... Connection refused" in CI
By Kaveh Alemi·Latchkey
A Selenium client could not connect to the WebDriver endpoint - a remote Grid/Standalone hub. The container is not running, is still starting, or the hub URL/port is wrong in the CI network.
What this error means
The client fails with "WebDriverException: ... Connection refused" or urllib3 "Max retries exceeded with url: /wd/hub/session." No session is created because the driver endpoint is unreachable.
selenium
urllib3.exceptions.MaxRetryError: HTTPConnectionPool(host='localhost',
port=4444): Max retries exceeded with url: /wd/hub/session
(Caused by NewConnectionError(...: Connection refused))
Common causes
Grid/Standalone container not ready
The remote Selenium container was started as a CI service but the client connected before it finished booting, or it never came up.
Wrong hub URL or port
The command_executor URL points to the wrong host/port for the CI network (service name vs localhost, missing /wd/hub).
How to fix it
Wait for the hub before connecting
Poll the Grid status endpoint until it is ready, then create the session.
Terminal
npx wait-on http://localhost:4444/wd/hub/status
# then run the tests
Point the client at the right endpoint
test_app.py
from selenium import webdriver
driver = webdriver.Remote(
command_executor='http://localhost:4444/wd/hub',
options=webdriver.ChromeOptions())
How to prevent it
Gate tests on the Grid /status endpoint being ready.
Keep the hub host/port in one shared config value.
Give the Grid container a generous readiness window on slow CI.
Frequently asked questions
What causes ""Connection refused""?
The remote Selenium container was started as a CI service but the client connected before it finished booting, or it never came up.
How do I fix "Connection refused"?
Poll the Grid status endpoint until it is ready, then create the session.
Can Latchkey fix this automatically?
Yes. Latchkey runs your GitHub Actions on managed runners that detect this failure, apply the fix, and retry the job automatically - self-healing is on by default.