{"record":{"id":"6b416c27554154b7","repo":"hasura/graphql-engine","slug":"autherror-0","errorCode":null,"errorMessage":"AuthError: {0}","messagePattern":"AuthError: (.+?)","errorType":"exception","errorClass":"ConnectionInitError","httpStatus":null,"severity":"error","filePath":"v3/crates/graphql/graphql-ws/src/protocol/init.rs","lineNumber":126,"sourceCode":"                            Err(ConnectionInitError::AlreadyInitialized)\n                        }\n                    }\n                })\n            },\n        )\n        .await\n}\n\n/// Error types that may occur during connection initialization.\n#[derive(Debug, thiserror::Error)]\npub enum ConnectionInitError {\n    #[error(\"Connection already initialized\")]\n    AlreadyInitialized,\n    #[error(\"Invalid header name: {0}\")]\n    InvalidHeaderName(#[from] http::header::InvalidHeaderName),\n    #[error(\"Invalid header value: {0}\")]\n    InvalidHeaderValue(#[from] http::header::InvalidHeaderValue),\n    #[error(\"AuthError: {0}\")]\n    Authn(#[from] AuthError),\n    #[error(\"SessionError: {0}\")]\n    Session(#[from] SessionError),\n}\n\nimpl tracing_util::TraceableError for ConnectionInitError {\n    fn visibility(&self) -> tracing_util::ErrorVisibility {\n        tracing_util::ErrorVisibility::User\n    }\n}\n\n/// Parses headers from a given map of strings into an `http::HeaderMap`.\n/// Returns a parsed header map or an error if the headers are invalid.\nfn parse_headers(map: HashMap<String, String>) -> Result<http::HeaderMap, ConnectionInitError> {\n    let mut headers = http::HeaderMap::new();\n    for (key, value) in map {\n        let header_name = http::HeaderName::from_bytes(key.as_bytes())?;\n        let header_value = http::HeaderValue::from_str(&value)?;","sourceCodeStart":108,"sourceCodeEnd":144,"githubUrl":"https://github.com/hasura/graphql-engine/blob/724551b9ae87845594ef0408cff0e50eb6c90dc5/v3/crates/graphql/graphql-ws/src/protocol/init.rs#L108-L144","documentation":"This is a passthrough of an `AuthError` that occurred while processing the `connection_init` message of the graphql-ws protocol. The connection-init handler authenticates the incoming payload (tokens, headers, credentials), and any authentication failure is wrapped in `ConnectionInitError::Authn`.","triggerScenarios":"Calling the connection-init flow with missing, expired, malformed, or rejected credentials — e.g. an `Authorization` header or token in the payload that the auth layer refuses. The auth subsystem returns `AuthError`, which this enum propagates.","commonSituations":"Expired or revoked API tokens; wrong issuer/audience in JWT validation; missing auth headers because a proxy stripped them; environment misconfiguration of auth secrets between services.","solutions":["Verify the token/credentials sent in the connection_init payload are present and not expired","Check the server-side auth configuration (issuer, audience, signing keys) matches the token","Log the inner AuthError to identify the specific cause (expired vs invalid vs missing)","Re-authenticate to obtain a fresh token and reconnect"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// decode & check expiry before connecting\nconst claims = JSON.parse(atob(token.split('.')[1]));\nif (claims.exp * 1000 < Date.now()) throw new Error('token expired');","typeGuard":null,"tryCatchPattern":"catch (e) { if (String(e).startsWith('AuthError:')) { await refreshToken(); reconnect(); } }","preventionTips":["Refresh tokens before expiry and reconnect on auth failure","Log inner AuthError details","Keep auth server config (issuer/audience) in sync across environments"],"tags":["graphql-ws","authentication","websocket","connection-init"],"backgroundTag":"authentication-failed","analyzedSha":"724551b9ae87845594ef0408cff0e50eb6c90dc5","analyzedAt":"2026-08-28T07:32:55.105Z","schemaVersion":2},"datasetVersion":"2026-08-28T11:17:15.048Z"}