{"record":{"id":"a7d21aa063047706","repo":"quarkusio/quarkus","slug":"unable-to-obtain-the-connection-from-the-vert-x-du-a7d21a","errorCode":null,"errorMessage":"Unable to obtain the connection from the Vert.x duplicated context","messagePattern":"Unable to obtain the connection from the Vert\\.x duplicated context","errorType":"exception","errorClass":"WebSocketServerException","httpStatus":null,"severity":"error","filePath":"extensions/websockets-next/runtime/src/main/java/io/quarkus/websockets/next/runtime/WebSocketServerRecorder.java","lineNumber":84,"sourceCode":"    private final RuntimeValue<WebSocketsServerRuntimeConfig> runtimeConfig;\n\n    public WebSocketServerRecorder(final RuntimeValue<WebSocketsServerRuntimeConfig> runtimeConfig) {\n        this.runtimeConfig = runtimeConfig;\n    }\n\n    public Supplier<Object> connectionSupplier() {\n        return new Supplier<Object>() {\n\n            @Override\n            public Object get() {\n                Context context = Vertx.currentContext();\n                if (context != null && VertxContext.isDuplicatedContext(context)) {\n                    Object connection = ContextSupport.WebSocketContextLocalsProvider.WEB_SOCKET_CONN_LOCAL.get(context);\n                    if (connection != null) {\n                        return connection;\n                    }\n                }\n                throw new WebSocketServerException(\"Unable to obtain the connection from the Vert.x duplicated context\");\n            }\n        };\n    }\n\n    public Handler<RoutingContext> createEndpointHandler(String generatedEndpointClass, String endpointId,\n            boolean activateRequestContext, boolean activateSessionContext, String endpointPath) {\n        ArcContainer container = Arc.container();\n        ConnectionManager connectionManager = container.instance(ConnectionManager.class).get();\n        Codecs codecs = container.instance(Codecs.class).get();\n        HttpUpgradeCheck[] httpUpgradeChecks = getHttpUpgradeChecks(endpointId, container);\n        TrafficLogger trafficLogger = TrafficLogger.forServer(runtimeConfig.getValue());\n        WebSocketTelemetryProvider telemetryProvider = container.instance(WebSocketTelemetryProvider.class).orElse(null);\n        return new Handler<RoutingContext>() {\n\n            @Override\n            public void handle(RoutingContext ctx) {\n                if (ctx.request().headers().contains(HandshakeRequest.SEC_WEBSOCKET_KEY)) {\n                    UserData userData = new UserDataImpl();","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/websockets-next/runtime/src/main/java/io/quarkus/websockets/next/runtime/WebSocketServerRecorder.java#L66-L102","documentation":"Thrown by the server-side WebSocket connection supplier when it cannot read the WebSocket connection from the Vert.x duplicated context local (WEB_SOCKET_CONN_LOCAL). The connection is only registered on the duplicated context bound to a live server connection; any other context yields null and this WebSocketServerException.","triggerScenarios":"Invoking WebSocketConnection APIs (via the injected Supplier) outside the endpoint's duplicated context — e.g. from a manually created thread, an executor, a timer, or after the connection closed and locals were cleared.","commonSituations":"Bridging to a separate thread pool without context propagation; calling connection-related code in application startup; storing the Supplier and calling it later from another request context.","solutions":["Run the code on the duplicated context of the connection (capture it and use context.runOnContext)","Avoid manual thread switching inside WebSocket endpoint callbacks; use Quarkus context-aware executors","Ensure the endpoint method executes while the connection is still open","If using @Blocking or scheduled work, re-attach the captured duplicated context before the call"],"exampleFix":"// before\nCompletableFuture.runAsync(() -> connection.sendBlocking(msg));\n// after\ncapturedContext.runOnContext(v -> connection.sendBlocking(msg));","handlingStrategy":"try-catch","validationCode":"io.vertx.core.Context ctx = Vertx.currentContext();\nboolean onDuplicated = ctx != null && io.quarkus.websockets.next.runtime.VertxContext.isDuplicatedContext(ctx);","typeGuard":"static boolean isServerConnection(Object c) {\n    return c instanceof io.quarkus.websockets.next.runtime.WebSocketConnectionImpl;\n}","tryCatchPattern":"try {\n    connection.send(msg);\n} catch (WebSocketServerException e) {\n    capturedDuplicatedContext.runOnContext(v -> connection.send(msg));\n}","preventionTips":["Run all connection work on the endpoint's duplicated context","Avoid manual thread pools in server endpoints; use Quarkus context propagation","Don't cache the connection Supplier for use after the connection closes","Prefer QuarkusSecureExecutorService / context-aware executors"],"tags":["websockets","vertx","context-local","threading","server"],"backgroundTag":"missing-duplicated-context","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}