org.openqa.selenium.remote.http.ConnectionFailedException: Unable to establish websocket connection Selenium ChromeDriver and Chrome v111

Using v111.0 this error message…

org.openqa.selenium.remote.http.ConnectionFailedException: Unable to establish websocket connection to http://localhost:49877/devtools/browser/3a3af47d-732a-4337-a91c-18c8ced545cd

and this error message…

2023-03-08T21:06:50.3319163Z WARNING: Invalid Status code=403 text=Forbidden
2023-03-08T21:06:50.3320374Z java.io.IOException: Invalid Status code=403 text=Forbidden

and even this error message…

java.lang.NullPointerException: Cannot invoke "org.asynchttpclient.ws.WebSocket.sendCloseFrame(int, String)" because "this.socket" is null

…is the result of devtools_http_handler rejecting an incoming WebSocket connection from the http://localhost origin.


Details

This issue is the result of Origin header when set is being auto-resolved into meaningless value in Netty 4.x currently being used by Selenium. This issue was discussed in details in Origin header is always sent from WebSocket client and was addressed through Fix generating the Origin header value for websocket handshake request.


Solution

As per the Selenium Blog there are a couple of approaches to solve this issue.

  • Using HTTP Client in Selenium: Selenium uses an HTTP client and associated WebSocket client for multiple purposes. AsyncHttpClient is an open-source library built on top of Netty. It allows the execution of HTTP requests and responses asynchronously. Additionally it also provides WebSocket support.But AsyncHttpClient is no more maintained since June 2021 as Java 11+ provides a built-in HTTP and WebSocket client. Selenium can utilize it to replace AsyncHttpClient.

    • Prerequisites:

      Project configured to use Java 11+
      Using Selenium 4.5.0 as a minumum version
      
    • Integrating the Java 11+ client: As Java 11+ HTTP client sits in its own artifact it can be imported into your project that use Java 11+ as follows:

      <dependency>
        <groupId>org.seleniumhq.selenium</groupId>
        <artifactId>selenium-java</artifactId>
        <version>4.5.0</version>
      </dependency>
      <dependency>
        <groupId>org.seleniumhq.selenium</groupId>
        <artifactId>selenium-http-jdk-client</artifactId>
        <version>4.5.0</version>
      </dependency>
      
    • Setting the system property: You need to set the system property to indicate that Java 11+ Http client needs to be used. By default, it uses the AsyncHttpClient:

      System.setProperty("webdriver.http.factory", "jdk-http-client");
      
  • Using in Selenium: As the ChromeDriver verbose log suggests:

    [32332:259:0214/190812.204658:ERROR:devtools_http_handler.cc(766)] Rejected an incoming WebSocket connection from the http://localhost:58642 origin. Use the command line flag --remote-allow-origins=http://localhost:58642 to allow connections from this origin or --remote-allow-origins=* to allow all origins.
    

A quick fix to this issue would be to add the argument --remote-allow-origins=* as follows:

  • Java:

    ChromeOptions options = new ChromeOptions();
    options.addArguments("--remote-allow-origins=*");
    WebDriver driver = new ChromeDriver(options);
    

References

Links to useful references:

Leave a Comment