eclipse-vertx/vert.x · error · java.lang.UnsupportedOperationException

HTTP/1.x connections don't support SETTINGS

Error message

HTTP/1.x connections don't support SETTINGS

What it means

This UnsupportedOperationException is thrown by Http1Connection.settings() because HTTP/1.x has no concept of HTTP/2 SETTINGS frames. The library's HttpConnection interface exposes HTTP/2-only operations, and the HTTP/1.x implementation deliberately rejects them instead of returning null or silently no-oping. It signals a programming error: code is calling HTTP/2-specific API surface on an HTTP/1.x connection.

Source

Thrown at vertx-core/src/main/java/io/vertx/core/http/impl/http1/Http1Connection.java:117

  @Override
  public Http1Connection exceptionHandler(Handler<Throwable> handler) {
    return (Http1Connection) super.exceptionHandler(handler);
  }

  @Override
  public HttpConnection goAway(long errorCode, int lastStreamId, Buffer debugData) {
    throw new UnsupportedOperationException("HTTP/1.x connections don't support GOAWAY");
  }

  @Override
  public HttpConnection goAwayHandler(@Nullable Handler<GoAway> handler) {
    throw new UnsupportedOperationException("HTTP/1.x connections don't support GOAWAY");
  }

  @Override
  public Http2Settings settings() {
    throw new UnsupportedOperationException("HTTP/1.x connections don't support SETTINGS");
  }

  @Override
  public Future<Void> updateSettings(HttpSettings settings) {
    throw new UnsupportedOperationException("HTTP/1.x connections don't support SETTINGS");
  }

  @Override
  public Http2Settings remoteSettings() {
    throw new UnsupportedOperationException("HTTP/1.x connections don't support SETTINGS");
  }

  @Override
  public HttpConnection remoteSettingsHandler(Handler<HttpSettings> handler) {
    throw new UnsupportedOperationException("HTTP/1.x connections don't support SETTINGS");
  }

  @Override

View on GitHub (pinned to fb308bd8c3)

Solutions

  1. Check the negotiated protocol before calling HTTP/2-only APIs: only invoke settings() when the request/endpoint is HTTP/2 (e.g. request.version() == HTTP_2 or SSLSession/ALPN shows h2).
  2. Configure the client/server to actually negotiate HTTP/2 (useTLS with ALPN h2, or h2c handling) if you intend to use SETTINGS-based tuning.
  3. If HTTP/1.x is the intended protocol, remove the settings()/updateSettings() calls and tune HTTP/1.x behavior via its own options (e.g. keep-alive, pipelining, max concurrent streams equivalents in HttpClientOptions).
  4. Wrap the call defensively: catch UnsupportedOperationException and fall back to HTTP/1.x-compatible behavior instead of crashing.
  5. Route HTTP/2-specific logic through a version check rather than assuming the HttpConnection implementation type; or use instanceof / class name checks against Http1Connection in internal code.

Example fix

// before
HttpConnection conn = request.connection();
Http2Settings s = conn.settings(); // throws on HTTP/1.x

// after
HttpConnection conn = request.connection();
Http2Settings s = null;
try {
  s = conn.settings();
} catch (UnsupportedOperationException e) {
  // HTTP/1.x connection: SETTINGS not applicable, use defaults
}
Defensive patterns

Strategy: try-catch

Validate before calling

boolean http2 = request.version() == HttpVersion.HTTP_2;
if (!http2) { /* skip settings() call, use HTTP/1.x defaults */ }

Type guard

static boolean isHttp2(HttpConnection c) {
  return !(c instanceof io.vertx.core.http.impl.http1.Http1Connection);
}

Try / catch

try {
  Http2Settings s = conn.settings();
  apply(s);
} catch (UnsupportedOperationException e) {
  // HTTP/1.x: no SETTINGS support, keep defaults
}

Prevention

When it happens

Trigger: Calling HttpConnection.settings() on a connection obtained from an HttpClientRequest/HttpClientResponse or HttpServerRequest whose protocol is HTTP/1.0 or HTTP/1.1. Typically code written for HTTP/2 (e.g. after upgrading to h2c or TLS+ALPN) is run against a plain HTTP/1.1 server or client connection.

Common situations: An app configured for HTTP/2 in production but connecting over plain TCP without h2c upgrade or ALPN negotiation, so it silently falls back to HTTP/1.1 and later hits HTTP/2-only tuning code (flow-control/limits via SETTINGS). Also generic connection-level middleware that calls settings() unconditionally, and tests running against HTTP/1.x while production uses h2.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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