SeleniumHQ/selenium · critical · Error::WebDriverError
unable to connect to #{@executable_path} #{@host}:#{@port}:
Error message
unable to connect to #{@executable_path} #{@host}:#{@port}: #{error} What it means
Raised by ServiceManager#connect_until_stable when the driver server process has been launched but does not respond with a ready status at /status within START_TIMEOUT (20 seconds). The method polls /status every 0.1s; if the endpoint never returns a successful HTTP response with ready: true before the deadline, it raises WebDriverError with the last connection error appended.
Source
Thrown at rb/lib/selenium/webdriver/common/service_manager.rb:142
end
end
def process_running?
defined?(@process) && @process&.alive?
end
def process_exited?
@process.nil? || @process.exited?
end
def connect_until_stable
deadline = current_time + START_TIMEOUT
loop do
error = check_connection_error
return unless error
raise Error::WebDriverError, "#{cannot_connect_error_text}: #{error}" if current_time > deadline
sleep 0.1
end
end
def check_connection_error
response = Net::HTTP.start(@host, @port, open_timeout: 0.5, read_timeout: 1) do |http|
http.get('/status', {'Connection' => 'close'})
end
return "status returned #{response.code}\n#{response.body}" unless response.is_a?(Net::HTTPSuccess)
status = JSON.parse(response.body)
ready = status['ready'] || status.dig('value', 'ready')
"driver not ready: #{response.body}" unless ready
rescue Errno::ECONNREFUSED, Errno::ECONNRESET, Errno::EPIPE, Errno::ETIMEDOUT,
Errno::EADDRNOTAVAIL, Errno::EHOSTUNREACH, Net::OpenTimeout, Net::ReadTimeout,
EOFError, SocketError, Net::HTTPBadResponse, JSON::ParserError => eView on GitHub (pinned to aa36b38e69)
Solutions
- Check the driver version matches the browser version (e.g., chromedriver --version vs chrome --version).
- Enable driver logging: pass log: $stdout or set SE_DEBUG=1 to see the driver's own error output.
- Increase startup timeout is not directly exposed; instead, verify the driver binary works standalone by running it manually: chromedriver --port=9515 and curl http://localhost:9515/status.
- Ensure the correct architecture binary is installed (x86_64 vs ARM64).
- Check for missing shared libraries: ldd /path/to/driver.
- Use Selenium Manager or specify a known-good driver_path explicitly.
Example fix
// before service = Selenium::WebDriver::Service.chrome driver = Selenium::WebDriver.for :chrome, service: service # fails: unable to connect to chromedriver // after (enable logging + explicit driver) service = Selenium::WebDriver::Service.chrome( driver_path: '/usr/local/bin/chromedriver-120', log: $stdout ) driver = Selenium::WebDriver.for :chrome, service: service
Defensive patterns
Strategy: retry
Validate before calling
# Pre-test: verify driver binary works standalone
def driver_responds?(driver_path, port = 9515)
pid = spawn(driver_path, "--port=#{port}")
sleep 2
ready = begin
response = Net::HTTP.get(URI("http://localhost:#{port}/status"))
JSON.parse(response)['value']['ready']
rescue StandardError
false
end
Process.kill('TERM', pid) rescue nil
Process.wait(pid) rescue nil
ready
end Try / catch
attempts = 0
begin
attempts += 1
driver = Selenium::WebDriver.for :chrome
rescue Selenium::WebDriver::Error::WebDriverError => e
raise unless e.message.include?('unable to connect') && attempts < 3
warn "Driver startup failed (attempt #{attempts}), retrying... #{e.message}"
sleep 2
retry
end Prevention
- Ensure browser and driver versions are matched before running tests.
- Enable driver logging (log: $stdout or SE_DEBUG=1) to capture driver-side errors.
- Run driver.quit in an ensure block / at_exit to prevent orphaned processes.
- In CI, add a pre-flight check that verifies the driver binary executes successfully.
When it happens
Trigger: The driver binary (chromedriver, geckodriver, etc.) starts but crashes immediately or hangs. The driver binary version is incompatible with the browser version. The driver binary requires specific flags not provided. Port contention where another process interferes. The driver is slow to start (heavy I/O, slow disk) and exceeds 20s. SELinux or firewall blocking localhost connections.
Common situations: Chrome browser updated but chromedriver is still the old version (session creation fails). Running under Docker with limited resources causing slow startup. Driver binary for wrong architecture (e.g., ARM binary on x86). Missing shared libraries for the driver binary (it starts then segfaults).
Related errors
- remote server not ready in {} seconds
- remote server not stopped in #{@timeout} seconds
- -> #{@pid} still alive after #{timeout} seconds
- invalid port: #{@port}
- unable to bind to locking port #{@port} within #{@timeout} s
AI-assisted analysis of SeleniumHQ/selenium@aa36b38e69 (2026-08-14).
Data as JSON: /api/errors/21e594eb57ec7f38.
Report an issue: GitHub.