hasura/graphql-engine · error · ConnectionInitError

AuthError: {0}

Error message

AuthError: {0}

What it means

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`.

Source

Thrown at v3/crates/graphql/graphql-ws/src/protocol/init.rs:126

                            Err(ConnectionInitError::AlreadyInitialized)
                        }
                    }
                })
            },
        )
        .await
}

/// Error types that may occur during connection initialization.
#[derive(Debug, thiserror::Error)]
pub enum ConnectionInitError {
    #[error("Connection already initialized")]
    AlreadyInitialized,
    #[error("Invalid header name: {0}")]
    InvalidHeaderName(#[from] http::header::InvalidHeaderName),
    #[error("Invalid header value: {0}")]
    InvalidHeaderValue(#[from] http::header::InvalidHeaderValue),
    #[error("AuthError: {0}")]
    Authn(#[from] AuthError),
    #[error("SessionError: {0}")]
    Session(#[from] SessionError),
}

impl tracing_util::TraceableError for ConnectionInitError {
    fn visibility(&self) -> tracing_util::ErrorVisibility {
        tracing_util::ErrorVisibility::User
    }
}

/// Parses headers from a given map of strings into an `http::HeaderMap`.
/// Returns a parsed header map or an error if the headers are invalid.
fn parse_headers(map: HashMap<String, String>) -> Result<http::HeaderMap, ConnectionInitError> {
    let mut headers = http::HeaderMap::new();
    for (key, value) in map {
        let header_name = http::HeaderName::from_bytes(key.as_bytes())?;
        let header_value = http::HeaderValue::from_str(&value)?;

View on GitHub (pinned to 724551b9ae)

Solutions

  1. Verify the token/credentials sent in the connection_init payload are present and not expired
  2. Check the server-side auth configuration (issuer, audience, signing keys) matches the token
  3. Log the inner AuthError to identify the specific cause (expired vs invalid vs missing)
  4. Re-authenticate to obtain a fresh token and reconnect
Defensive patterns

Strategy: retry

Validate before calling

// decode & check expiry before connecting
const claims = JSON.parse(atob(token.split('.')[1]));
if (claims.exp * 1000 < Date.now()) throw new Error('token expired');

Try / catch

catch (e) { if (String(e).startsWith('AuthError:')) { await refreshToken(); reconnect(); } }

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of hasura/graphql-engine@724551b9ae (2026-08-28). Data as JSON: /api/errors/6b416c27554154b7. Report an issue: GitHub.