{"record":{"id":"7587737eeecf4015","repo":"vi/websocat","slug":"requested-sec-websocket-protocol-does-not-match-server","errorCode":null,"errorMessage":"Requested Sec-WebSocket-Protocol does not match --server-protocol option","messagePattern":"Requested Sec-WebSocket-Protocol does not match --server-protocol option","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/ws_server_peer.rs","lineNumber":189,"sourceCode":"                                );\n                            }\n                        }\n                    }\n                }\n\n                for (hn, hv) in custom_reply_headers {\n                    x.headers.append_raw(hn, hv);\n                }\n\n                debug!(\"{:?}\", x.request);\n                debug!(\"{:?}\", x.headers);\n\n                if !protocol_check {\n                    return Box::new(\n                            x.reject()\n                                .and_then(|_| {\n                                    warn!(\"Requested Sec-WebSocket-Protocol does not match --server-protocol option\");\n                                    ::futures::future::err(crate::util::simple_err(\n                                        \"Requested Sec-WebSocket-Protocol does not match --server-protocol option\"\n                                            .to_string(),\n                                    ))\n                                })\n                                .map_err(|e| websocket::WebSocketError::IoError(io_other_error(e))),\n                        )\n                            as Box<dyn Future<Item = Peer, Error = websocket::WebSocketError>>;\n                }\n                \n                \n                match l2r {\n                    L2rUser::FillIn(ref y) => {\n                        let uri = &x.request.subject.1;\n                        let mut z = y.borrow_mut();\n                        z.uri = Some(format!(\"{}\", uri));\n\n                        let h : &websocket::header::Headers = &x.request.headers;\n                        for q in opts.headers_to_env.iter() {","sourceCodeStart":171,"sourceCodeEnd":207,"githubUrl":"https://github.com/vi/websocat/blob/3a3574cd2f5d17857d87f3982e72c3ede159dde0/src/ws_server_peer.rs#L171-L207","documentation":"Raised during WebSocket upgrade in ws_upgrade_peer when the client's Sec-WebSocket-Protocol header does not include any protocol listed via the --server-protocol option. The server rejects the handshake, logs a warning, and returns a simple_err wrapped as a WebSocketError::IoError, aborting the upgrade. This is a deliberate protocol-negotiation check to enforce that clients speak one of the allowed subprotocols.","triggerScenarios":"A WebSocket client connects to the server (ws_upgrade_peer, invoked from construct) with a Sec-WebSocket-Protocol header that does not match the value(s) given to --server-protocol, or omits the header entirely while --server-protocol is configured and protocol_check fails.","commonSituations":"Client was not configured with the required subprotocol (e.g. browser WebSocket without the protocols argument); mismatch between --server-protocol on the server and the client library's subprotocol option; typos or case variations in the protocol name; server config updated but clients not redeployed.","solutions":["Set the client's subprotocol to match --server-protocol (e.g. new WebSocket(url, '<protocol>') or the equivalent option in your client library).","Compare the exact --server-protocol value on the server command line with the client's Sec-WebSocket-Protocol header (check for typos/case).","If no subprotocol should be required, remove the --server-protocol option so the check is skipped.","Confirm the server was restarted after changing --server-protocol and that no proxy strips the Sec-WebSocket-Protocol header."],"exampleFix":"// before: client does not request the subprotocol\nconst ws = new WebSocket(\"ws://host:8080/echo\");\n\n// after: request the protocol the server requires (--server-protocol chat)\nconst ws = new WebSocket(\"ws://host:8080/echo\", \"chat\");","handlingStrategy":"validation","validationCode":"// Client-side pre-check before connecting (JS)\nconst required = \"chat\"; // must equal server's --server-protocol\nif (!required) throw new Error(\"--server-protocol value must be known to the client\");\nconst ws = new WebSocket(url, required);","typeGuard":null,"tryCatchPattern":"ws.addEventListener(\"error\", () => {\n  // rejected handshake: subprotocol did not match --server-protocol\n  console.error(\"Upgrade rejected: Sec-WebSocket-Protocol mismatch; check --server-protocol\");\n});","preventionTips":["Always pass the subprotocol in the client constructor when the server sets --server-protocol.","Keep the protocol string in shared config on both sides instead of hardcoding.","Test handshake with a raw client (curl/websocat) showing the Sec-WebSocket-Protocol header after any server config change."],"tags":["websocket","handshake","protocol-negotiation","configuration"],"backgroundTag":"invalid-config-value","analyzedSha":"3a3574cd2f5d17857d87f3982e72c3ede159dde0","analyzedAt":"2026-09-12T15:14:27.766Z","contentChangedAt":"2026-09-12T15:14:27.766Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}