eclipse-vertx/vert.x · error · IllegalArgumentException

Scheme:

Error message

Scheme: 

What it means

WebSocketClientImpl.webSocketConnectOptionsAbs parses a WebSocket URL passed to the client and requires its scheme to be exactly ws or wss. If the URI's scheme is anything else (http, https, missing scheme, or a typo), it throws IllegalArgumentException("Scheme: " + scheme) so the connect request never proceeds with a non-WebSocket endpoint.

Source

Thrown at vertx-core/src/main/java/io/vertx/core/http/impl/WebSocketClientImpl.java:149

  public Future<WebSocket> webSocket(int port, String host, String requestURI) {
    return webSocket(new WebSocketConnectOptions().setURI(requestURI).setHost(host).setPort(port));
  }

  public Future<WebSocket> webSocket(WebSocketConnectOptions options) {
    return webSocket(vertx.getOrCreateContext(), options);
  }

  static WebSocketConnectOptions webSocketConnectOptionsAbs(String url, MultiMap headers, WebSocketVersion version, List<String> subProtocols) {
    URI uri;
    try {
      uri = new URI(url);
    } catch (URISyntaxException e) {
      throw new IllegalArgumentException(e);
    }
    String scheme = uri.getScheme();
    if (!"ws".equals(scheme) && !"wss".equals(scheme)) {
      throw new IllegalArgumentException("Scheme: " + scheme);
    }
    boolean ssl = scheme.length() == 3;
    int port = uri.getPort();
    if (port == -1) port = ssl ? 443 : 80;
    StringBuilder relativeUri = new StringBuilder();
    if (uri.getRawPath() != null) {
      relativeUri.append(uri.getRawPath());
    }
    if (uri.getRawQuery() != null) {
      relativeUri.append('?').append(uri.getRawQuery());
    }
    if (uri.getRawFragment() != null) {
      relativeUri.append('#').append(uri.getRawFragment());
    }
    return new WebSocketConnectOptions()
      .setHost(uri.getHost())
      .setPort(port).setSsl(ssl)
      .setURI(relativeUri.toString())

View on GitHub (pinned to fb308bd8c3)

Solutions

  1. Change the URL to use the ws:// or wss:// scheme (wss for TLS, which also selects port 443/SSL)
  2. If you only have an http(s) URL, derive the scheme: http->ws, https->wss
  3. Trim whitespace and validate the URL before passing it to webSocket()
  4. Prefer passing WebSocketConnectOptions with explicit host/port/ssl/uri instead of a raw URL string

Example fix

// before
client.webSocket("https://example.com/events", ws -> {...});
// after
client.webSocket("wss://example.com/events", ws -> {...});
Defensive patterns

Strategy: validation

Validate before calling

static boolean isValidWsUrl(String url) {
  try {
    java.net.URI u = new java.net.URI(url);
    return "ws".equals(u.getScheme()) || "wss".equals(u.getScheme());
  } catch (URISyntaxException e) { return false; }
}

Try / catch

try {
  client.webSocket(url, ws -> {...});
} catch (IllegalArgumentException e) {
  if (e.getMessage() != null && e.getMessage().startsWith("Scheme:")) {
    throw new IllegalArgumentException("URL must use ws:// or wss://: " + url, e);
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling webSocket()/webSocketAbs with a URL like "http://host/sock", "//host/path", "host:9999/path" (no scheme, so uri.getScheme() is the hostname or null), or "WS://host" (case-sensitive comparison fails only if server-side, but here scheme is lowercased by URI parsing, so mostly wrong scheme or missing scheme).

Common situations: Config value taken from an environment variable or property meant for an HTTP URL reused for WebSockets; users forgetting to swap http->ws or https->wss; URLs built by string concatenation that omit the scheme; trailing/leading whitespace producing a null or mangled scheme.

Understand the failure class

Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.

Related errors


AI-assisted analysis of eclipse-vertx/vert.x@fb308bd8c3 (2026-09-06). Data as JSON: /api/errors/b5519cc4d418a657. Report an issue: GitHub.