{"record":{"id":"bc87b0402ce0bb1f","repo":"karatelabs/karate","slug":"unexpected-fullhttpresponse-status-response-status-content","errorCode":null,"errorMessage":"unexpected FullHttpResponse (status=${response.status()}, content=${response.content()})","messagePattern":"unexpected FullHttpResponse \\(status=(.+?), content=(.+?)\\)","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"karate-core/src/main/java/io/karatelabs/http/WsClientHandler.java","lineNumber":88,"sourceCode":"        client.handleDisconnect();\n    }\n\n    @Override\n    protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {\n        if (!handshaker.isHandshakeComplete()) {\n            try {\n                handshaker.finishHandshake(ctx.channel(), (FullHttpResponse) msg);\n                logger.debug(\"websocket handshake complete: {}\", client.getUri());\n                handshakeFuture.setSuccess();\n            } catch (WebSocketHandshakeException e) {\n                logger.error(\"websocket handshake failed: {}\", e.getMessage());\n                handshakeFuture.setFailure(e);\n            }\n            return;\n        }\n\n        if (msg instanceof FullHttpResponse response) {\n            throw new IllegalStateException(\n                    \"unexpected FullHttpResponse (status=\" + response.status() +\n                            \", content=\" + response.content().toString(StandardCharsets.UTF_8) + \")\");\n        }\n\n        WebSocketFrame frame = (WebSocketFrame) msg;\n\n        if (frame instanceof TextWebSocketFrame textFrame) {\n            onTextFrame(ctx, textFrame);\n        } else if (frame instanceof BinaryWebSocketFrame binaryFrame) {\n            onBinaryFrame(ctx, binaryFrame);\n        } else if (frame instanceof PingWebSocketFrame pingFrame) {\n            onPingFrame(ctx, pingFrame);\n        } else if (frame instanceof PongWebSocketFrame pongFrame) {\n            onPongFrame(ctx, pongFrame);\n        } else if (frame instanceof CloseWebSocketFrame closeFrame) {\n            onCloseFrame(ctx, closeFrame);\n        }\n    }","sourceCodeStart":70,"sourceCodeEnd":106,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-core/src/main/java/io/karatelabs/http/WsClientHandler.java#L70-L106","documentation":"WsClientHandler.channelRead0 throws IllegalStateException when a FullHttpResponse arrives after (or outside) the expected handshake processing. In a normal WebSocket lifecycle the handshake response is consumed once; any subsequent full HTTP response on the channel means the pipeline received something it cannot interpret as a WebSocket frame, so the library fails loudly and fails the handshake future.","triggerScenarios":"Server responds with an HTTP error page (e.g. 401/403/404/500) instead of completing the 101 upgrade; duplicate/malformed handshake handling; an HTTP response arriving on an already-established WebSocket channel.","commonSituations":"Auth gateway returning 302/401 HTML for wss:// requests; reverse proxy intercepting the upgrade; wrong path on the server; server version returning an error after partial handshake.","solutions":["Check the handshakeFuture failure/cause and inspect the status/content in the message to see what the server returned","Verify the WebSocket endpoint URL, path and auth headers (Authorization, cookies) are correct","Ensure any proxy in front of the server supports and forwards the HTTP Upgrade for WebSocket","Capture a wire-level trace (or server access log) of the handshake request/response to confirm a 101 Switching Protocols"],"exampleFix":"// before\nclient.connect(\"wss://host/api/ws\"); // /api/ws returns 404 JSON page\n// after\nclient.connect(\"wss://host/ws\"); // correct endpoint returns 101","handlingStrategy":"try-catch","validationCode":"// pre-flight: confirm the endpoint performs a WS upgrade\nHttpRequest req = HttpRequest.newBuilder(URI.create(wsUrl.replaceFirst(\"^ws\", \"http\"))).GET().build();\n// expect non-error response and Upgrade headers; a 404/401 page predicts this IllegalStateException","typeGuard":null,"tryCatchPattern":"try { client.connect(url).get(10, TimeUnit.SECONDS); } catch (ExecutionException e) { if (e.getCause() instanceof IllegalStateException && e.getCause().getMessage().startsWith(\"unexpected FullHttpResponse\")) { log.error(\"server rejected upgrade: {}\", e.getCause().getMessage()); } }","preventionTips":["Confirm the ws URL path exists and the handshake returns 101","Attach auth headers/cookies the server requires for the upgrade","Ensure proxies/load balancers forward Upgrade and Connection headers","Read the status/content in the error message to diagnose server rejection"],"tags":["websocket","handshake","http-response","netty"],"backgroundTag":"unexpected-response-shape","analyzedSha":"a22eb90246d958d15a47bf436693d0121ad2812d","analyzedAt":"2026-09-12T09:01:00.220Z","contentChangedAt":"2026-09-12T09:01:00.220Z","schemaVersion":2},"datasetVersion":"2026-09-16T19:17:19.609Z"}