SeleniumHQ/selenium · error · Error::WebDriverError

empty body: #{content_type.inspect} (#{code}) #{body}

Error message

empty body: #{content_type.inspect} (#{code})
#{body}

What it means

Raised as Error::WebDriverError by Http::Common#create_response when the response has a JSON content-type but the body is empty (after stripping). A JSON content-type promises a parseable JSON body; an empty body means the server violated its own contract, so JSON.parse would fail. The error includes the content-type and status code for diagnosis.

Source

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

              result = str.dup.force_encoding(Encoding::UTF_8)
              return result if result.valid_encoding?
            end

            str.encode(Encoding::UTF_8)
          rescue EncodingError => e
            raise Error::WebDriverError,
                  "Unable to encode string to UTF-8: #{e.message}. " \
                  "String encoding: #{str.encoding}, content: #{str.inspect}"
          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

View on GitHub (pinned to aa36b38e69)

Solutions

  1. Check Selenium Server / Grid logs for crashes or errors at the time of the request.
  2. Inspect network infrastructure (proxies, load balancers) for response body truncation.
  3. Retry the request; transient empty bodies from server restarts often succeed on retry.
  4. Verify server health and resource limits (memory, file descriptors) on the grid nodes.

Example fix

# No code fix; diagnose server-side:
# 1. Check grid node logs for crashes
# 2. Verify proxy configuration preserves response bodies
# Retry transient failures:
# begin
#   driver.navigate.to(url)
# rescue Selenium::WebDriver::Error::WebDriverError => e
#   retry if e.message.include?('empty body')
# end
Defensive patterns

Strategy: retry

Validate before calling

# No caller-side prevention; this is a server-side response contract violation.
# Monitor server health proactively:
# Net::HTTP.get(URI('http://grid:4444/status'))

Try / catch

retries = 0
begin
  driver.navigate.to(url)
rescue Selenium::WebDriver::Error::WebDriverError => e
  raise unless e.message.include?('empty body') && retries < 3
  retries += 1
  sleep 2 ** retries
  retry
end

Prevention

When it happens

Trigger: The remote Selenium Server returns Content-Type: application/json with a 200 status but zero-length body. A proxy or load balancer strips the body but preserves headers. The server crashes mid-response after sending headers. A misconfigured grid router returns an empty JSON response.

Common situations: Selenium Grid node crashes during session creation. Reverse proxies (nginx, Envoy) misconfigured to buffer/truncate responses. Network interruptions that close the connection after headers. Server Out-Of-Memory kills that truncate the response. Cloud provider endpoints with buggy response handling.

Related errors


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