SeleniumHQ/selenium · error · Error::WebDriverError

unexpected response, code=#{code}, content-type=#{content_ty

Error message

unexpected response, code=#{code}, content-type=#{content_type.inspect}
#{body}

What it means

Raised as Error::WebDriverError by Http::Common#create_response when the response has a non-JSON content-type, is not a 204, and the body is non-empty. Unlike the empty-body variant, this includes the response body text so the developer can see what the server actually returned — typically an HTML error page, a proxy error, or a misrouted response.

Source

Thrown at rb/lib/selenium/webdriver/remote/http/common.rb:155

          end

          def create_response(code, body, content_type)
            code = code.to_i
            body = body.to_s.strip
            content_type = content_type.to_s
            WebDriver.logger.debug("<- #{body}", id: :command)

            if content_type.include? CONTENT_TYPE
              raise Error::WebDriverError, "empty body: #{content_type.inspect} (#{code})\n#{body}" if body.empty?

              Response.new(code, JSON.parse(body))
            elsif code == 204
              Response.new(code)
            else
              msg = if body.empty?
                      "unexpected response, code=#{code}, content-type=#{content_type.inspect}"
                    else
                      "unexpected response, code=#{code}, content-type=#{content_type.inspect}\n#{body}"
                    end

              raise Error::WebDriverError, msg
            end
          end
        end # Common
      end # Http
    end # Remote
  end # WebDriver
end # Selenium

View on GitHub (pinned to aa36b38e69)

Solutions

  1. Read the response body in the error message — it usually identifies what service answered (HTML title, proxy name).
  2. Verify the remote URL and path are correct for your Selenium Server version.
  3. Ensure the Selenium Server / Grid is actually running and healthy: curl http://host:4444/status.
  4. Check for corporate proxies or VPNs intercepting the connection to the grid.

Example fix

# The error body will say e.g. "<html><title>502 Bad Gateway</title>..."
# Fix: ensure the Selenium Grid is running and reachable
# $ curl -s http://grid:4444/status | jq .value.ready
# If false or unreachable, start/restart the grid.
Defensive patterns

Strategy: try-catch

Validate before calling

# Pre-flight check: confirm the endpoint is a Selenium Server
require 'net/http'
uri = URI(server_url + '/status')
resp = Net::HTTP.get_response(uri)
raise "Endpoint returned #{resp.content_type}, expected JSON" unless resp.content_type.include?('application/json')

Try / catch

begin
  Selenium::WebDriver.for(:remote, url: server_url, options: opts)
rescue Selenium::WebDriver::Error::WebDriverError => e
  raise unless e.message.include?('unexpected response')
  # e.message contains the HTML body — read it to identify the service
  raise "Not a Selenium Server at #{server_url}: #{e.message}"
end

Prevention

When it happens

Trigger: The server returns an HTML 404/500 error page. A reverse proxy returns an HTML error (e.g. nginx 502 Bad Gateway). The WebDriver client hits a non-Selenium HTTP service. The Selenium Server returns an HTML landing page instead of a JSON API response.

Common situations: Wrong URL — hitting a web server instead of the Selenium Server. Grid hub down and a load balancer returning an HTML error page. Selenium Server not started but something else listening on port 4444. Authentication pages from corporate proxies. Version mismatch where the server endpoint path changed.

Related errors


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