SeleniumHQ/selenium · error · Error

remote server not stopped in #{@timeout} seconds

Error message

remote server not stopped in #{@timeout} seconds

What it means

Selenium::Server wraps the standalone Selenium Grid/server jar process. After you request a shutdown, poll_for_shutdown checks the listening socket (via SocketPoller); if the server's port is still accepting connections past @timeout seconds, this Error is raised because the server never came down. It is a liveness check on a process you asked to stop.

Source

Thrown at rb/lib/selenium/server.rb:294

      start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
      loop do
        return if status_ok?

        elapsed = Process.clock_gettime(Process::CLOCK_MONOTONIC) - start_time
        raise Error, "remote server not ready in #{@timeout} seconds" if elapsed > @timeout

        sleep 0.5
      end
    end

    def socket_connected?
      @socket_connected ||= socket.connected?
    end

    def poll_for_shutdown
      return if socket.closed?

      raise Error, "remote server not stopped in #{@timeout} seconds"
    end

    def socket
      @socket ||= WebDriver::SocketPoller.new(@host, @port, @timeout)
    end
  end # Server
end # Selenium

View on GitHub (pinned to aa36b38e69)

Solutions

  1. Pass a larger shutdown timeout, e.g. server.stop(60), or Selenium::Server.new(..., timeout: 60).
  2. Confirm the port is actually the Selenium server: `lsof -i :<port>` / `netstat` and that no stale java process holds it.
  3. Kill any orphaned server process from a previous run before starting a new one.
  4. Use a server jar version matching your Selenium client version, and ensure the host/port passed to Selenium::Server match the real listener.
  5. Call server.stop in an ensure block and rescue Selenium::WebDriver::Error to avoid masking test failures.

Example fix

// before
server = Selenium::Server.new('/path/selenium-server.jar')
server.stop
// after
server = Selenium::Server.new('/path/selenium-server.jar', timeout: 90)
at_exit { server.stop(90) rescue nil }
Defensive patterns

Strategy: validation

Validate before calling

require 'socket'

# Before stop: confirm the host/port is the Selenium server and pick a sane timeout.
def selenium_port_open?(host, port)
  sock = TCPSocket.new(host, port) rescue nil
  return false unless sock
  sock.close
  true
end

server.stop(selenium_port_open?(host, port) ? 90 : 10)

Try / catch

begin
  server.stop(90)
rescue Selenium::WebDriver::Error => e
  warn "Server did not stop in time: #{e.message}"
  # leave it; OS will reap, or kill by PID
end

Prevention

When it happens

Trigger: Calling Selenium::Server#stop (or letting a server with a block go out of scope) where the managed server jar keeps the TCP port open longer than the configured @timeout. Triggered whenever stop poll_for_shutdown finds socket.closed? still false at the end of the wait window.

Common situations: Server jar version mismatch/hang, slow JVM/container startup of shutdown, another process (or a previous stale java instance) holding the port, very low timeout default on a loaded CI machine, host/port misconfigured so SocketPoller probes the wrong service.

Understand the failure class

Related errors


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