{"record":{"id":"938ebf707585802b","repo":"eclipse-vertx/vert.x","slug":"http-1-x-connections-don-t-support-ping","errorCode":null,"errorMessage":"HTTP/1.x connections don't support PING","messagePattern":"HTTP/1\\.x connections don't support PING","errorType":"exception","errorClass":"java.lang.UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"vertx-core/src/main/java/io/vertx/core/http/impl/http1/Http1Connection.java","lineNumber":137,"sourceCode":"\n  @Override\n  public Future<Void> updateSettings(HttpSettings settings) {\n    throw new UnsupportedOperationException(\"HTTP/1.x connections don't support SETTINGS\");\n  }\n\n  @Override\n  public Http2Settings remoteSettings() {\n    throw new UnsupportedOperationException(\"HTTP/1.x connections don't support SETTINGS\");\n  }\n\n  @Override\n  public HttpConnection remoteSettingsHandler(Handler<HttpSettings> handler) {\n    throw new UnsupportedOperationException(\"HTTP/1.x connections don't support SETTINGS\");\n  }\n\n  @Override\n  public HttpConnection pingHandler(@Nullable Handler<Buffer> handler) {\n    throw new UnsupportedOperationException(\"HTTP/1.x connections don't support PING\");\n  }\n\n  @Override\n  public Future<Buffer> ping(Buffer data) {\n    throw new UnsupportedOperationException(\"HTTP/1.x connections don't support PING\");\n  }\n\n  @Override\n  protected long sizeof(Object obj) {\n    // https://github.com/netty/netty/issues/12708\n    // try first Netty HTTP singleton types, without any instanceof/checkcast bytecodes\n    if (obj == Unpooled.EMPTY_BUFFER || obj == LastHttpContent.EMPTY_LAST_CONTENT) {\n      return 0;\n    }\n    // try known vertx (non-interface) types: bi-morphic\n    if (obj instanceof VertxAssembledHttpResponse) {\n      return ((VertxAssembledHttpResponse) obj).content().readableBytes();\n    }","sourceCodeStart":119,"sourceCodeEnd":155,"githubUrl":"https://github.com/eclipse-vertx/vert.x/blob/fb308bd8c3f12c79f4ae89bef67fadf6c80d036e/vertx-core/src/main/java/io/vertx/core/http/impl/http1/Http1Connection.java#L119-L155","documentation":"Thrown by Http1Connection.pingHandler(Handler<Buffer>) because HTTP/1.x has no PING frame; application-level connection keepalive pings are an HTTP/2 feature. The HTTP/1.x implementation rejects handler registration with UnsupportedOperationException, as it does for the other HTTP/2-only operations on this class.","triggerScenarios":"Calling conn.pingHandler(handler) on an HTTP/1.x connection to observe peer keepalive pings or measure RTT — for example in shared connection health-check code that registers ping handlers for every connection independent of protocol.","commonSituations":"Keepalive/latency-monitoring middleware built for HTTP/2 applied to mixed-protocol deployments; clients silently downgraded to HTTP/1.1 because the server or an intermediary lacks h2 support; health-check frameworks instrumenting pooled HTTP/1.1 connections; migration from Netty/other HTTP/2 stacks where ping handling existed for all versions.","solutions":["Register pingHandler only when the connection is HTTP/2; for HTTP/1.x use TCP-level or request-based keepalive checks instead.","Guard registration with try/catch (UnsupportedOperationException) so instrumentation code is protocol-agnostic.","Enable HTTP/2 negotiation (ALPN h2 over TLS, or h2c prior knowledge) if ping-based keepalive/RTT measurement is required.","For HTTP/1.x liveness, implement an application-level heartbeat (small periodic request) rather than relying on PING frames."],"exampleFix":"// before\nconn.pingHandler(pong -> recordRtt());\n\n// after\ntry {\n  conn.pingHandler(pong -> recordRtt());\n} catch (UnsupportedOperationException e) {\n  // HTTP/1.x: use a lightweight periodic request as keepalive instead\n}","handlingStrategy":"try-catch","validationCode":"if (request.version() == HttpVersion.HTTP_2) {\n  conn.pingHandler(handler);\n}","typeGuard":"static boolean supportsPing(HttpConnection c) {\n  return !(c instanceof io.vertx.core.http.impl.http1.Http1Connection);\n}","tryCatchPattern":"try {\n  conn.pingHandler(pong -> recordRtt());\n} catch (UnsupportedOperationException e) {\n  // HTTP/1.x: fall back to periodic lightweight request keepalive\n}","preventionTips":["Use protocol-conditional registration for ping/pong keepalive instrumentation.","Design HTTP/1.x fallback keepalive (small periodic request or TCP keepalive) for mixed-protocol deployments.","Catch UnsupportedOperationException in shared health-check helpers so they work on any connection type.","Verify the full path negotiates h2 (server, ALPN, proxies) if PING-based liveness is required."],"tags":["http","http2","http1","unsupported-operation","ping"],"backgroundTag":"unsupported-operation","analyzedSha":"fb308bd8c3f12c79f4ae89bef67fadf6c80d036e","analyzedAt":"2026-09-06T11:37:12.241Z","contentChangedAt":"2026-09-06T11:37:12.241Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}