zeroclaw-labs/zeroclaw · error · anyhow::Error

Host '{host}' is not in http_request.allowed_domains

Error message

Host '{host}' is not in http_request.allowed_domains

What it means

Thrown by HttpRequestTool::validate_url_policy (crates/zeroclaw-tools/src/http_request.rs:165) when the URL host does not match any entry in http_request.allowed_domains. Matching is case-insensitive, ignores a trailing dot, and supports parent-domain entries (allowlisting "example.com" also permits "api.example.com") plus the "*" wildcard. A host in allowed_private_hosts is exempt from this check.

Source

Thrown at crates/zeroclaw-tools/src/http_request.rs:165

                    "Blocked link-local host: {host}; 169.254.0.0/16 is blocked unconditionally \
                     because cloud metadata services are hosted in that range"
                );
            }
        }
        let port = extract_port(url)?;

        let private_host = domain_guard::is_private_or_local_host(&host);
        let private_host_explicitly_allowed = private_host
            && domain_guard::host_matches_allowlist(&host, &self.allowed_private_hosts);

        if private_host && !private_host_explicitly_allowed && !self.allow_private_hosts {
            anyhow::bail!("Blocked local/private host: {host}");
        }

        if !private_host_explicitly_allowed
            && !domain_guard::host_matches_allowlist(&host, &self.allowed_domains)
        {
            anyhow::bail!("Host '{host}' is not in http_request.allowed_domains");
        }

        let private_resolution_allowed = self.allow_private_hosts
            || domain_guard::host_matches_allowlist(&host, &self.allowed_private_hosts);

        let canonical_url = if host.parse::<IpAddr>().is_ok() {
            url.to_string()
        } else {
            let mut parsed = reqwest::Url::parse(url)
                .map_err(|e| anyhow::Error::msg(format!("Invalid URL format: {e}")))?;
            parsed
                .set_host(Some(&host))
                .map_err(|_| anyhow::Error::msg("URL contains an invalid host"))?;
            parsed.to_string()
        };

        Ok(HttpRequestUrlPolicy {
            url: canonical_url,

View on GitHub (pinned to 88bb9c8533)

Solutions

  1. Add the exact host (or its registrable parent domain) to [http_request] allowed_domains and restart.
  2. Set allowed_domains = ["*"] if all public hosts should be reachable (private/metadata hosts are still blocked separately).
  3. Check for near-misses: scheme vs host, www prefix, staging vs prod domain, trailing dot, and Punycode/IDN spellings.

Example fix

# before
[http_request]
allowed_domains = ["example.com"]
# request to https://api.github.com fails

# after
[http_request]
allowed_domains = ["example.com", "api.github.com"]
Defensive patterns

Strategy: validation

Validate before calling

fn host_in_allowlist(host: &str, allowed: &[String]) -> bool {
    let h = host.trim_end_matches('.').to_lowercase();
    allowed.iter().any(|a| a == "*" || h == *a || h.ends_with(&format!(".{a}")))
}

Try / catch

let result = tool.execute(args).await?;
if let Some(err) = &result.error {
    if err.contains("is not in http_request.allowed_domains") {
        // extract host, propose allowlist addition or reject the target
    }
}

Prevention

When it happens

Trigger: allowed_domains = ["example.com"] but requesting "https://google.com"; allowlisting the subdomain "api.example.com" and then requesting the apex "https://example.com" (parent matching is one-directional); requesting a literal IP that is not allowlisted; typos or www vs bare domain mismatches ("www.example.com" matches an "example.com" entry, but not vice versa when the entry is "www.example.com").

Common situations: Forgetting to allowlist a new API endpoint after rollout; environments (prod vs staging) with different allowlists; agents following redirects to CDN or auth domains not in the list; assuming allowlist is path- or port-based (it is host-only).

Related errors


AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23). Data as JSON: /api/errors/80a703f2a0fe27b7. Report an issue: GitHub.