hasura/graphql-engine · error · Error
Invalid header name {0}
Error message
Invalid header name {0} What it means
The pre-route hook supplied a header name that is not a valid HTTP header name (invalid characters, empty, or malformed), and the executor rejected it while applying hook instructions to the request. The offending name is included as {0}.
Source
Thrown at v3/crates/plugins/pre-route-plugin/src/execute.rs:34
use tracing_util::{
ErrorVisibility, SpanVisibility, Traceable, TraceableError, set_attribute_on_active_span,
};
#[derive(Debug, thiserror::Error)]
pub enum Error {
#[error("Error while making the HTTP request to the pre-parse plugin {0} - {1}")]
ErrorWhileMakingHTTPRequestToTheHook(String, reqwest::Error),
#[error("Error while building the request for the pre-parse plugin {0} - {1}")]
BuildRequestError(String, String),
#[error("Reqwest error: {0}")]
ReqwestError(reqwest::Error),
#[error("Unexpected status code: {0}")]
UnexpectedStatusCode(u16),
#[error("Error parsing the request: {0}")]
PluginRequestParseError(serde_json::error::Error),
#[error("HTTP method {0} not supported")]
UnsupportedHTTPMethod(String),
#[error("Invalid header name {0}")]
InvalidHeaderName(String),
#[error("Invalid header value {0}")]
InvalidHeaderValue(String),
#[error("Not found")]
NotFound,
// Only used in the pre-route plugin handler function. Defined to ensure consistent
// response formatting in IntoResponse impl.
#[error("Cannot load pre-route plugins: {0}")]
CannotLoadPlugins(String),
}
impl TraceableError for Error {
fn visibility(&self) -> ErrorVisibility {
ErrorVisibility::Internal
}
}
impl IntoResponse for Error {View on GitHub (pinned to 724551b9ae)
Solutions
- Validate header names in the hook with http::HeaderName::from_str before returning them.
- Whitelist allowed header names the hook may set.
- Trim input and reject names containing spaces, colons, or control characters.
- Log the offending name from the error message to locate the source.
Example fix
// before (hook)
instructions.push(HeaderOp { name: user_input, value });
// after (hook)
let name = http::HeaderName::from_str(user_input.trim())
.map_err(|_| Error::InvalidHeaderName(user_input.into()))?;
instructions.push(HeaderOp { name: name.to_string(), value }); Defensive patterns
Strategy: validation
Validate before calling
fn valid_header_name(name: &str) -> bool {
!name.is_empty() && http::HeaderName::from_str(name).is_ok()
} Type guard
fn is_valid_header_name(n: &str) -> bool {
http::HeaderName::from_str(n.trim()).is_ok()
} Try / catch
if let Error::InvalidHeaderName(name) = &e { tracing::warn!("dropping invalid header from hook: {name}"); } Prevention
- Validate header names with http::HeaderName::from_str in the hook before returning.
- Allowlist headers a hook may set.
- Sanitize user-sourced strings of CR/LF and spaces.
When it happens
Trigger: The hook's response instructs the engine to add/override a header with a name containing spaces, non-ASCII characters, or CR/LF — anything http::HeaderName::from_str would reject.
Common situations: Hook passing through unvalidated user input as header names; header name typos; header-injection attempts or accidental newlines in config-driven header maps.
Related errors
- Error while building the request for the pre-parse plugin {0
- User error from plugin {plugin_name}
- Error while building the request for the pre-parse plugin {0
- Error while building the request for the pre-parse plugin {0
- Error while preparing the response: {0}
AI-assisted analysis of hasura/graphql-engine@724551b9ae (2026-08-28).
Data as JSON: /api/errors/bbe958426f9b96b5.
Report an issue: GitHub.