hasura/graphql-engine · error · Error

Invalid URL for auth webhook: {0}

Error message

Invalid URL for auth webhook: {0}

What it means

A hard error from auth config generation: the configured authentication webhook URL cannot be parsed as a valid URL. The webhook is the endpoint the engine calls to authenticate requests, so an unparseable URL aborts the build.

Source

Thrown at v3/crates/auth/hasura-authn/src/lib.rs:289

    InvalidHeaderName(String),
    #[error("Header value '{0}' is not a valid header value for header '{1}' in the auth config")]
    InvalidHeaderValue(String, String),
}

impl Warning {
    pub fn should_be_an_error(&self, flags: &open_dds::flags::OpenDdFlags) -> bool {
        match self {
            Warning::InvalidHeaderName(_) | Warning::InvalidHeaderValue(_, _) => {
                flags.contains(open_dds::flags::Flag::DisallowInvalidHeadersInAuthConfig)
            }
            _ => false,
        }
    }
}

#[derive(Debug, thiserror::Error, PartialEq)]
pub enum Error {
    #[error("Invalid URL for auth webhook: {0}")]
    InvalidAuthWebhookUrl(String),
    #[error("{0}")]
    AuthConfigWarningsAsErrors(SeparatedBy<Warning>),
    #[error("Duplicate alternative mode identifier: '{0}'")]
    DuplicateAlternativeModeIdentifier(String),
}

// A small utility type which exists for the sole purpose of displaying a vector with a certain
// separator.
#[derive(Debug, PartialEq)]
pub struct SeparatedBy<T> {
    pub lines_of: Vec<T>,
    pub separator: String,
}

impl<T: Display> Display for SeparatedBy<T> {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        for (index, elem) in self.lines_of.iter().enumerate() {

View on GitHub (pinned to 724551b9ae)

Solutions

  1. Fix the webhook URL to include scheme and host, e.g. https://auth.example.com/webhook
  2. Check for stray whitespace, quotes, or unreplaced environment variables in the URL string
  3. Verify the URL parses with a standard parser (e.g. `url::Url::parse`) before rebuilding

Example fix

// before
webhook: { url: "auth.example.com/webhook" }
// after
webhook: { url: "https://auth.example.com/webhook" }
Defensive patterns

Strategy: validation

Validate before calling

use url::Url;
let webhook_url = Url::parse(&auth_config.webhook.url)
    .map_err(|e| format!("invalid auth webhook URL: {e}"))?;
if !matches!(webhook_url.scheme(), "http" | "https") {
    return Err("webhook URL must be http(s)".into());
}

Type guard

fn isWebhookUrlValid(u: &str) -> bool { url::Url::parse(u).map(|x| x.has_host()).unwrap_or(false) }

Try / catch

match build_auth_config(&metadata) {
    Err(Error::InvalidAuthWebhookUrl(bad)) => fail_deploy_with_context("fix webhook URL", bad),
    r => r,
}

Prevention

When it happens

Trigger: The `webhook` field of the auth config contains a string that fails standard URL parsing (missing scheme, embedded spaces, malformed percent-encoding, etc.).

Common situations: Missing https:// prefix, trailing whitespace or template placeholders left unreplaced, using a service name without a scheme in Kubernetes-style configs, or typos introduced during config refactors.

Related errors


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