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");
}
@OverrideView on GitHub (pinned to fb308bd8c3)
Solutions
- 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).
- Configure the client/server to actually negotiate HTTP/2 (useTLS with ALPN h2, or h2c handling) if you intend to use SETTINGS-based tuning.
- 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).
- Wrap the call defensively: catch UnsupportedOperationException and fall back to HTTP/1.x-compatible behavior instead of crashing.
- 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
- Check request.version() (or ALPN result) before calling HTTP/2-only HttpConnection methods.
- Keep HTTP/2 tuning code in a separate path guarded by protocol checks.
- Catch UnsupportedOperationException once in a shared helper that wraps all HTTP/2-only connection calls.
- Verify h2 negotiation (ALPN/h2c) in integration tests if settings tuning is part of the flow.
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
- HTTP/1.x connections don't support PING
- Cannot write an HTTP/2 frame over an HTTP/1.x connection
- size must be > 0
- http2MaxPoolSize must be > 0
- a header name cannot contain non-ASCII character:
AI-assisted analysis of eclipse-vertx/vert.x@fb308bd8c3 (2026-09-06).
Data as JSON: /api/errors/39b3fb4a6b476e19.
Report an issue: GitHub.