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
- Fix the header name to a valid HTTP token (letters, digits, and - _ . ~ ! # $ & ' * + ^ ` |), e.g. 'X-My-Header'
- Validate/normalize header names before putting them into the connection_init payload; pass values separately, never 'Name: value' combined
- Sanitize configuration strings (trim whitespace/newlines) when headers come from env vars or config files
- 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
- Whitelist/validate client-supplied header names in the connection_init payload
- Never pass 'Name: value' strings as header names; split them first
- Trim whitespace and reject control characters in header config from env/config files
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
- subscription are not supported over HTTP
- Connection already initialized
- Expecting {} protocol
- Connection initialization timed out
- Unable to parse WebSocket message: {0}
AI-assisted analysis of hasura/graphql-engine@724551b9ae (2026-08-28).
Data as JSON: /api/errors/0be103ed9f605be1.
Report an issue: GitHub.