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 => e

View on GitHub (pinned to aa36b38e69)

Solutions

  1. Check the driver version matches the browser version (e.g., chromedriver --version vs chrome --version).
  2. Enable driver logging: pass log: $stdout or set SE_DEBUG=1 to see the driver's own error output.
  3. 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.
  4. Ensure the correct architecture binary is installed (x86_64 vs ARM64).
  5. Check for missing shared libraries: ldd /path/to/driver.
  6. 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

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


AI-assisted analysis of SeleniumHQ/selenium@aa36b38e69 (2026-08-14). Data as JSON: /api/errors/21e594eb57ec7f38. Report an issue: GitHub.