hasura/graphql-engine · error · ConnectionInitError

Invalid header name: {0}

Error message

Invalid header name: {0}

What it means

ConnectionInitError::InvalidHeaderName wraps http::header::InvalidHeaderName and occurs when a header name supplied during graphql-ws connection initialization is not syntactically valid. HTTP/1 header names must be valid HTTP tokens (no spaces, control characters, or non-token separators), so headers derived from connection_init payload parameters fail validation when malformed.

Source

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

                            let session = authorize_identity(&auth_response.identity, &headers)?;
                            Ok((session, headers))
                        }
                        ConnectionInitState::Initialized { .. } => {
                            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> {

View on GitHub (pinned to 724551b9ae)

Solutions

  1. Fix the header name to a valid HTTP token (letters, digits, and - _ . ~ ! # $ & ' * + ^ ` |), e.g. 'X-My-Header'
  2. Validate/normalize header names before putting them into the connection_init payload; pass values separately, never 'Name: value' combined
  3. Sanitize configuration strings (trim whitespace/newlines) when headers come from env vars or config files
  4. If forwarding arbitrary metadata, use a fixed header name and put variable data in the value

Example fix

// before
{"type":"connection_init","payload":{"headers":{"X Custom: id":"abc"}}}

// after
{"type":"connection_init","payload":{"headers":{"x-custom-id":"abc"}}}
Defensive patterns

Strategy: validation

Validate before calling

fn valid_header_name(name: &str) -> bool {
    !name.is_empty()
        && name.bytes().all(|b| match b {
            b'!' | b'#' | b'$' | b'%' | b'&' | b'\'' | b'*' | b'+' | b'-' | b'.'
            | b'^' | b'_' | b'`' | b'|' | b'~' => true,
            b if b.is_ascii_alphanumeric() => true,
            _ => false,
        })
}

Type guard

fn is_valid_header_name(name: &str) -> bool {
    http::header::HeaderName::try_from(name).is_ok()
}

Try / catch

match ws_conn.initialize_with_headers(payload, headers).await {
    Err(ConnectionInitError::InvalidHeaderName(e)) => {
        respond_bad_request(format!("invalid header name: {e}"));
    }
    Err(e) => respond_init_error(e),
    Ok(()) => (),
}

Prevention

When it happens

Trigger: The connection_init handshake attempts to build HTTP headers (e.g. forwarding auth or custom headers from the init payload) and a header name contains invalid characters — spaces, colons, CR/LF, or non-ASCII — causing HeaderName::from_str / try_from to fail during init.

Common situations: Client-supplied header maps in the connection_init payload with names like 'X My Header' or 'Authorization:'; headers configured via env/config strings with trailing whitespace or newlines; forwarding arbitrary user input as header names without validation; injecting full 'Name: value' strings as the name field.

Related errors


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