hasura/graphql-engine · error · BuildRequestError

Invalid header value for header {header_name}: {error}

Error message

Invalid header value for header {header_name}: {error}

What it means

The engine could not convert a configured header's value into an http::HeaderValue while building the request to the pre-NDC-request plugin. Header values must be visible ASCII (32-127, plus tab) and reasonably short; the error names the header and carries the underlying InvalidHeaderValue. Binary or non-ASCII session data in a forwarded header is a common cause.

Source

Thrown at v3/crates/plugins/pre-ndc-request-plugin/src/execute.rs:46

        plugin_name: String,
        error: serde_json::Value,
    },
    #[error("User error from plugin {plugin_name}")]
    PluginUserError {
        plugin_name: String,
        error: serde_json::Value,
    },
}

#[derive(Debug, thiserror::Error)]
pub enum BuildRequestError {
    #[error("Invalid header name {header_name}: {error}")]
    InvalidHeaderName {
        header_name: String,
        #[source]
        error: InvalidHeaderName,
    },
    #[error("Invalid header value for header {header_name}: {error}")]
    InvalidHeaderValue {
        header_name: HeaderName,
        #[source]
        error: InvalidHeaderValue,
    },
    #[error("Failed to convert session: {0}")]
    SessionConversionError(String),
    #[error("Failed to convert session variable '{variable_name}': {error}")]
    SessionVariableConversionError {
        variable_name: SessionVariableName,
        error: serde_json::Error,
    },
    #[error("Serialization error: {0}")]
    SerializationError(#[from] serde_json::Error),
}

impl TraceableError for Error {
    fn visibility(&self) -> ErrorVisibility {

View on GitHub (pinned to 724551b9ae)

Solutions

  1. Sanitize or percent-encode the value before it is forwarded as a header
  2. Confirm the session variable you forward is expected to be ASCII text (ids, not names)
  3. Restrict forwarded session variables to a known-safe allowlist in config
  4. If unicode must be passed, base64-encode it on the plugin side

Example fix

// before
let v = HeaderValue::from_str(&raw_unicode)?;
// after
let v = HeaderValue::from_str(&percent_encode(raw_unicode.as_bytes(), NON_ALPHANUMERIC).to_string())?;
Defensive patterns

Strategy: validation

Validate before calling

fn ascii_header_value(v: &str) -> bool {
    v.len() < 8192 && v.bytes().all(|b| (32..=127).contains(&b) || b == b'\t')
}

Prevention

When it happens

Trigger: Forwarding a session variable into a header where the value contains non-ASCII bytes (e.g. raw JWT bytes, UUIDs with BOM, unicode user names) and HeaderValue::from_str fails during request construction.

Common situations: Forwarding arbitrary user profile fields as headers; values pulled from session/JWT claims containing non-ASCII characters; header values exceeding server length limits.

Related errors


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