xai-org/grok-build · error

hook HTTP client config is valid

Error message

hook HTTP client config is valid

What it means

build_hook_client constructs a reqwest client for hook HTTP calls with a total timeout and redirects disabled (SSRF hardening: only the initial URL is validated) and .expect()s success. A panic means the reqwest/TLS builder rejected the configuration or the crypto backend failed to initialize.

Source

Thrown at crates/codegen/xai-grok-hooks/src/runner/http.rs:134

        if is_blocked_ip(&addr.ip()) {
            return Err(format!(
                "URL host {host} resolves to blocked private/internal IP: {}",
                addr.ip()
            ));
        }
    }

    Ok(())
}

fn build_hook_client(timeout_ms: u64) -> reqwest::Client {
    xai_grok_extra_ca::build_reqwest_client(|builder| {
        builder
            .timeout(Duration::from_millis(timeout_ms))
            // SECURITY: only the initial URL is SSRF-validated; do not follow redirects.
            .redirect(reqwest::redirect::Policy::none())
    })
    .expect("hook HTTP client config is valid")
}

pub async fn run_http_hook(
    spec: &HookSpec,
    envelope: &HookEventEnvelope,
    ctx: &RunContext<'_>,
    mode: GateKind,
) -> HookRunOutput {
    let start = Instant::now();

    let Some(ref raw_url) = spec.url else {
        return (
            HookRunnerResult::Failed("http hook has no 'url' field".into()),
            start.elapsed(),
            None,
            None,
        );
    };

View on GitHub (pinned to bc7f02eddd)

Solutions

  1. Ensure rustls/aws-lc-rs features are consistent across the workspace and rebuild
  2. Check no other component installed an incompatible global rustls CryptoProvider before hooks initialize
  3. Build the hook client once at startup (fail fast) rather than per-hook-execution
  4. If needed, inject a prebuilt client into the hook runner instead of relying on build_hook_client

Example fix

// before
let client = build_hook_client(timeout_ms); // panics if build fails
// after
let client = std::panic::catch_unwind(|| build_hook_client(timeout_ms))
    .map_err(|_| anyhow!("hook HTTP client unavailable: TLS init failed"))
    .unwrap_or_else(|_| reqwest::blocking::Client::new());
Defensive patterns

Strategy: try-catch

Validate before calling

let client = std::panic::catch_unwind(|| build_hook_client(timeout_ms))
    .map_err(|_| anyhow!("hook HTTP client build failed (TLS init?)"))?;

Type guard

null

Try / catch

let result = std::panic::catch_unwind(|| run_http_hook(spec, envelope, ctx).await)
    .await
    .map_err(|_| anyhow!("hook runner unavailable: HTTP client build failed"))?;

Prevention

When it happens

Trigger: Calling build_hook_client (from run_http_hook or hook_client_does_not_follow_redirects) when build_reqwest_client fails - TLS provider init failure, CA load failure, or invalid builder options in the current build/environment.

Common situations: Environment lacking working TLS/crypto prerequisites; mismatched rustls feature flags; conflicting process-level crypto provider installed by another component before hooks run.

Related errors


AI-assisted analysis of xai-org/grok-build@bc7f02eddd (2026-08-31). Data as JSON: /api/errors/4c80720ef807eb1f. Report an issue: GitHub.