{"record":{"id":"c35b026f7ef6d4fc","repo":"n0-computer/iroh","slug":"unsupportedwebsocketversion","errorCode":"UnsupportedWebsocketVersion","errorMessage":"invalid header value for {SEC_WEBSOCKET_VERSION}: unsupported websocket version, only supporting {SUPPORTED_WEBSOCKET_VERSION}","messagePattern":"invalid header value for (.+?): unsupported websocket version, only supporting (.+?)","errorType":"http","errorClass":"RelayUpgradeReqError","httpStatus":null,"severity":"error","filePath":"iroh-relay/src/server/http_server.rs","lineNumber":598,"sourceCode":"        ) -> Result<&HeaderValue, RelayUpgradeReqError> {\n            req.headers()\n                .get(&header)\n                .ok_or_else(|| e!(RelayUpgradeReqError::MissingHeader { header }))\n        }\n\n        let upgrade_header = expect_header(&req, UPGRADE)?;\n        ensure!(\n            upgrade_header == HeaderValue::from_static(WEBSOCKET_UPGRADE_PROTOCOL),\n            RelayUpgradeReqError::InvalidHeader {\n                header: UPGRADE,\n                details: format!(\"value must be {WEBSOCKET_UPGRADE_PROTOCOL}\")\n            }\n        );\n\n        let key = expect_header(&req, SEC_WEBSOCKET_KEY)?.clone();\n        let version = expect_header(&req, SEC_WEBSOCKET_VERSION)?.clone();\n\n        ensure!(\n            version.as_bytes() == SUPPORTED_WEBSOCKET_VERSION.as_bytes(),\n            RelayUpgradeReqError::UnsupportedWebsocketVersion\n        );\n\n        let subprotocols = expect_header(&req, SEC_WEBSOCKET_PROTOCOL)?\n            .to_str()\n            .ok()\n            .ok_or_else(|| {\n                e!(RelayUpgradeReqError::InvalidHeader {\n                    header: SEC_WEBSOCKET_PROTOCOL,\n                    details: \"header value is not ascii\".to_string()\n                })\n            })?;\n        let protocol_version = subprotocols\n            .split(\",\")\n            .map(|s| s.trim())\n            .filter_map(ProtocolVersion::match_from_str)\n            .max()","sourceCodeStart":580,"sourceCodeEnd":616,"githubUrl":"https://github.com/n0-computer/iroh/blob/2b4de030ce5e0133f272871a76f0c685c63f552a/iroh-relay/src/server/http_server.rs#L580-L616","documentation":"A relay WebSocket upgrade request carried a Sec-WebSocket-Version header that does not match the single version the relay server supports (13). The server rejects the upgrade before establishing the relay connection. This is thrown in handle_relay_ws_upgrade when version != SUPPORTED_WEBSOCKET_VERSION.","triggerScenarios":"Sending a WebSocket handshake to the iroh relay HTTP server with a Sec-WebSocket-Version header other than the supported value (e.g. '8' or '7'), or omitting/garbling the header so it fails the byte comparison against SUPPORTED_WEBSOCKET_VERSION.","commonSituations":"Custom or hand-rolled relay clients that implement the WS handshake themselves, proxies or middlewares that rewrite/drop the version header, older WS client libraries defaulting to draft versions (hixie-76 / hybi-08).","solutions":["Send Sec-WebSocket-Version: 13 in the WS handshake headers (any standard modern WS client does this by default).","Use the official iroh client/endpoint code to connect to the relay instead of a hand-rolled handshake.","If behind a proxy, configure it to pass the Sec-WebSocket-Version header through unchanged.","Check the client library version for known draft-version defaults and upgrade it."],"exampleFix":"// before (hand-rolled handshake)\nlet req = Request::builder().uri(relay_url).header(\"Sec-WebSocket-Version\", \"8\").body(...)?;\n// after\nlet req = Request::builder().uri(relay_url).header(\"Sec-WebSocket-Version\", \"13\").body(...)?;","handlingStrategy":"validation","validationCode":"const WS_VERSION: &str = \"13\";\nfn is_supported_ws_version(headers: &[(String, String)]) -> bool {\n    headers.iter().any(|(k, v)| k.eq_ignore_ascii_case(\"sec-websocket-version\") && v.trim() == WS_VERSION)\n}","typeGuard":"fn supported_version(v: &str) -> Option<&str> { (v == \"13\").then_some(v) }","tryCatchPattern":"match res {\n    Err(RelayUpgradeReqError::UnsupportedWebsocketVersion) => respond_400(\"unsupported websocket version\"),\n    other => other,\n}","preventionTips":["Always let a mainstream WS client set the version header (it sends 13 by default).","Never strip Sec-* headers in proxies.","Pin client library versions and review their handshake defaults.","Add an integration test against your relay endpoint."],"tags":["websocket","relay","handshake","protocol-version"],"backgroundTag":"invalid-argument-value","analyzedSha":"2b4de030ce5e0133f272871a76f0c685c63f552a","analyzedAt":"2026-09-08T04:26:47.755Z","contentChangedAt":"2026-09-08T04:26:47.755Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}