SeleniumHQ/selenium · critical · Error::ServerError
status code #{response.code}; payload #{response.payload}
Error message
status code #{response.code}; payload #{response.payload} What it means
Raised as Error::ServerError by Response#assert_ok when the HTTP response code is >= 400 (or nil) AND the response payload does not contain a recognized W3C error name that Error.for_error can map. assert_ok first tries to extract a specific error (e.g. NoSuchElementError) from the payload's value.error field; if unmapped, it falls back to ServerError with the raw status code and payload for diagnosis. This is the catch-all for unmapped server-side failures.
Source
Thrown at rb/lib/selenium/webdriver/remote/response.rb:56
error, message, backtrace = process_error
klass = Error.for_error(error) || return
ex = klass.new(message)
add_cause(ex, error, backtrace)
ex
end
def [](key)
@payload[key]
end
private
def assert_ok
e = error
raise e if e
return unless @code.nil? || @code >= 400
raise Error::ServerError, self
end
def add_cause(ex, error, backtrace)
cause = Error::WebDriverError.new
backtrace = backtrace_from_remote(backtrace) if backtrace.is_a?(Array)
cause.set_backtrace(backtrace)
raise ex, cause: cause
rescue Error.for_error(error)
ex
end
def backtrace_from_remote(server_trace)
server_trace.filter_map do |frame|
next unless frame.is_a?(Hash)
file = frame['fileName']
line = frame['lineNumber']
method = frame['methodName']View on GitHub (pinned to aa36b38e69)
Solutions
- Inspect the full error message — it includes the status code and payload, which usually reveals the server-side problem.
- Check Selenium Server / Grid logs for the matching error at the same timestamp.
- If the status is 5xx and intermittent, retry with backoff — it may be a transient server overload.
- Update the Selenium Server/Grid and client gem to matching versions to ensure error name compatibility.
- If using a third-party remote endpoint, consult its docs for the non-standard error format.
Example fix
# ServerError includes the code + payload; log it for diagnosis:
# begin
# driver.find_element(id: 'missing')
# rescue Selenium::WebDriver::Error::ServerError => e
# puts e.message # "status code 500; payload {\"value\":{\"error\":\"unknown error\",...}}"
# # check grid logs, retry if transient
# end
#
# For transient 5xx, wrap with retry:
# retries = 0
# begin
# driver.navigate.to(url)
# rescue Selenium::WebDriver::Error::ServerError => e
# raise if retries >= 3
# retries += 1
# sleep 2 ** retries
# retry
# end Defensive patterns
Strategy: try-catch
Validate before calling
# No caller-side prevention for unmapped server errors, but you can pre-check server health: require 'net/http' resp = Net::HTTP.get_response(URI(server_url + '/status')) raise 'Grid not ready' unless JSON.parse(resp.body)['value']['ready']
Try / catch
retries = 0 begin driver.find_element(id: target) rescue Selenium::WebDriver::Error::ServerError => e # e.message includes the status code and payload for diagnosis raise if retries >= 3 || !e.message.match?(/status code 5\d\d/) retries += 1 sleep 2 ** retries retry end
Prevention
- Always log the full ServerError message — the payload reveals the server-side cause.
- Check Selenium Server / Grid logs at the matching timestamp.
- Implement retry with exponential backoff for transient 5xx ServerErrors.
- Keep the Selenium Server/Grid and client gem versions aligned for error-name compatibility.
- Monitor grid health via the /status endpoint proactively.
When it happens
Trigger: The remote server returns a 5xx status with a payload whose 'error' field is not in the W3C error name table (Error.for_error returns nil). A 4xx with a non-standard error body. A server bug producing an unexpected status code. The server returns an error in a legacy (non-W3C) format that the error mapper doesn't recognize.
Common situations: Selenium Server / Grid internal errors (500) with non-standard error payloads. Non-W3C-compliant remote endpoints (older Selenium 2 servers, third-party services). Transient server-side failures during heavy load. Browser driver crashes producing unmapped errors. Network-layer issues surfaced as HTTP errors by the server.
Related errors
- empty body: #{content_type.inspect} (#{code}) #{body}
- unexpected response, code=#{code}, content-type=#{content_ty
- ${msg}
- Unknown error: ${JSON.stringify(data)}
- Invalid PointerInput kind '{kind}'
AI-assisted analysis of SeleniumHQ/selenium@aa36b38e69 (2026-08-14).
Data as JSON: /api/errors/9c86b72018e5f68d.
Report an issue: GitHub.