{"record":{"id":"fff6f829c002ec11","repo":"hasura/graphql-engine","slug":"expecting-protocol","errorCode":null,"errorMessage":"Expecting {} protocol","messagePattern":"Expecting (.+?) protocol","errorType":"http","errorClass":"WebSocketError","httpStatus":400,"severity":"error","filePath":"v3/crates/graphql/graphql-ws/src/websocket/mod.rs","lineNumber":122,"sourceCode":"        );\n\n        result.unwrap_or_else(IntoResponse::into_response)\n    }\n}\n\n/// Error types for WebSocket connections.\n#[derive(Debug, thiserror::Error)]\npub enum WebSocketError {\n    /// Error when the Sec-WebSocket-Protocol header is missing\n    #[error(\"Missing {SEC_WEBSOCKET_PROTOCOL} header\")]\n    MissingProtocolHeader,\n\n    /// Error when the header value cannot be converted to a string\n    #[error(\"{SEC_WEBSOCKET_PROTOCOL} header: {0}\")]\n    InvalidHeaderValue(#[from] ToStrError),\n\n    /// Error when the GraphQL WebSocket protocol is not included\n    #[error(\"Expecting {} protocol\", protocol::GRAPHQL_WS_PROTOCOL)]\n    ExpectingGraphqlWsProtocol,\n\n    /// Error when setting the WebSocket ID header value fails in response\n    #[error(\"Unable to set {SEC_WEBSOCKET_ID} header value: {0}\")]\n    WebSocketIdInvalidHeaderValue(#[from] InvalidHeaderValue),\n}\n\nimpl tracing_util::TraceableError for WebSocketError {\n    fn visibility(&self) -> tracing_util::ErrorVisibility {\n        match self {\n            Self::MissingProtocolHeader\n            | Self::ExpectingGraphqlWsProtocol\n            | Self::InvalidHeaderValue(_) => tracing_util::ErrorVisibility::User,\n            Self::WebSocketIdInvalidHeaderValue(_) => tracing_util::ErrorVisibility::Internal,\n        }\n    }\n}\n","sourceCodeStart":104,"sourceCodeEnd":140,"githubUrl":"https://github.com/hasura/graphql-engine/blob/724551b9ae87845594ef0408cff0e50eb6c90dc5/v3/crates/graphql/graphql-ws/src/websocket/mod.rs#L104-L140","documentation":"This error is thrown by the graphql-ws WebSocket handler when a client attempts to connect without requesting the expected GraphQL over WebSocket subprotocol (the Sec-WebSocket-Protocol header does not include the graphql-ws protocol string). The server rejects the upgrade because it can only speak the graphql-ws protocol. It is part of the connection negotiation errors in the websocket module.","triggerScenarios":"Opening a WebSocket connection to the GraphQL endpoint with a client that does not set Sec-WebSocket-Protocol: graphql-ws (e.g. a raw ws library, a wrong protocol name like graphql-ws old 'subscriptions-transport-ws', or a proxy that strips the subprotocol header).","commonSituations":"Using a generic WebSocket client instead of a GraphQL WS client; version mismatches where the client uses the older 'graphiql-transport-ws'/'subscriptions-transport-ws' protocol; reverse proxies (nginx, API gateways) dropping the Sec-WebSocket-Protocol header.","solutions":["Set the subprotocol on the client: new WebSocket(url, 'graphql-ws') or the equivalent option in your GraphQL WS client library","Verify no proxy between client and server strips the Sec-WebSocket-Protocol header","If you must support legacy clients, use a client that speaks the graphql-ws protocol (e.g. graphql-ws npm package instead of subscriptions-transport-ws)"],"exampleFix":"// before\nconst ws = new WebSocket('wss://example.com/graphql');\n\n// after\nconst ws = new WebSocket('wss://example.com/graphql', 'graphql-ws');","handlingStrategy":"validation","validationCode":"const ws = new WebSocket(url, 'graphql-ws');\nif (!['graphql-ws'].includes(ws.protocol)) {\n  throw new Error(`Unexpected subprotocol: ${{ws.protocol}}`);\n}","typeGuard":"function hasGraphqlWsProtocol(ws: WebSocket): boolean {{\n  return ws.protocol === 'graphql-ws';\n}}","tryCatchPattern":null,"preventionTips":["Always pass 'graphql-ws' as the WebSocket subprotocol when constructing the client","Use a maintained GraphQL WS client library rather than raw sockets","Test WebSocket connections through the same proxy configuration as production"],"tags":["websocket","graphql","protocol","connection-negotiation","rust"],"backgroundTag":"websocket-subprotocol-mismatch","analyzedSha":"724551b9ae87845594ef0408cff0e50eb6c90dc5","analyzedAt":"2026-08-28T07:32:55.105Z","schemaVersion":2},"datasetVersion":"2026-08-28T11:17:15.048Z"}