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
- Pass a larger shutdown timeout, e.g. server.stop(60), or Selenium::Server.new(..., timeout: 60).
- Confirm the port is actually the Selenium server: `lsof -i :<port>` / `netstat` and that no stale java process holds it.
- Kill any orphaned server process from a previous run before starting a new one.
- Use a server jar version matching your Selenium client version, and ensure the host/port passed to Selenium::Server match the real listener.
- 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
- Always wrap server.stop in an ensure block and rescue Selenium::WebDriver::Error.
- Pass an explicit, generous timeout for shutdown on slow/CI environments.
- Track the server PID so you can kill it if poll_for_shutdown times out.
- Reap stale java/server processes before starting a fresh Selenium::Server.
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
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- remote server not ready in {} seconds
- Timed out waiting for Selenium server at {self.status_url}
- Timed out waiting for response to BiDi command {current_id}
- {} for {}
- {}
AI-assisted analysis of SeleniumHQ/selenium@aa36b38e69 (2026-08-14).
Data as JSON: /api/errors/ff2b155e4db46757.
Report an issue: GitHub.