zeroclaw-labs/zeroclaw · error · anyhow::Error
HTTP request tool is enabled but no allowed_domains are conf
Error message
HTTP request tool is enabled but no allowed_domains are configured. Add [http_request].allowed_domains in config.toml
What it means
Thrown by HttpRequestTool::validate_url_policy (crates/zeroclaw-tools/src/http_request.rs:135) when the tool is enabled but its allowed_domains list is empty. The http_request tool is allowlist-only by design (fail closed): with no allowlist configured it cannot decide what is permitted, so every request is rejected before any DNS or network work. The message tells you the exact config.toml key to add.
Source
Thrown at crates/zeroclaw-tools/src/http_request.rs:135
}
fn validate_url_policy(&self, raw_url: &str) -> anyhow::Result<HttpRequestUrlPolicy> {
let url = raw_url.trim();
if url.is_empty() {
anyhow::bail!("URL cannot be empty");
}
if url.chars().any(char::is_whitespace) {
anyhow::bail!("URL cannot contain whitespace");
}
if !url.starts_with("http://") && !url.starts_with("https://") {
anyhow::bail!("Only http:// and https:// URLs are allowed");
}
if self.allowed_domains.is_empty() {
anyhow::bail!(
"HTTP request tool is enabled but no allowed_domains are configured. Add [http_request].allowed_domains in config.toml"
);
}
let host = extract_host(url)?;
if let Ok(ip) = host.parse::<IpAddr>() {
if domain_guard::is_known_cloud_metadata_endpoint(ip) {
anyhow::bail!("Blocked cloud metadata host: {host}");
}
if domain_guard::is_cloud_metadata_ip(ip) {
anyhow::bail!(
"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)?;
View on GitHub (pinned to 88bb9c8533)
Solutions
- Add the allowlist to config.toml, e.g. [http_request] with allowed_domains = ["example.com", "api.github.com"], then restart.
- Use allowed_domains = ["*"] if you truly want all public hosts (private/metadata hosts stay blocked regardless).
- If constructing the tool programmatically, pass a non-empty Vec<String> of domains to HttpRequestTool::new/new_with_config.
Example fix
# before # config.toml has no [http_request] section -> every request fails # after [http_request] allowed_domains = ["example.com", "api.github.com"]
Defensive patterns
Strategy: validation
Validate before calling
if allowed_domains.is_empty() {
anyhow::bail!("refusing to enable http_request: set [http_request].allowed_domains in config.toml");
}
let tool = HttpRequestTool::new_with_config(security, allowed_domains, /* ... */)?; Try / catch
let result = tool.execute(args).await?;
if let Some(err) = &result.error {
if err.contains("no allowed_domains are configured") {
// surface a setup error to the operator; do not retry
}
} Prevention
- Add a startup assertion that http_request is only registered when allowed_domains is non-empty.
- Keep the [http_request] block in the canonical config template so fresh installs inherit it.
- Run config validation (parse + required keys) before the agent starts.
When it happens
Trigger: Constructing HttpRequestTool::new(...) with an empty allowed_domains Vec; enabling the http_request tool in config.toml without an [http_request] section; a config.toml where the [http_request] table exists but allowed_domains is missing, commented out, or set to an empty array; CI using a minimal config that omitted the section.
Common situations: Fresh installs or docker images shipped without the [http_request] block; config refactors that renamed or dropped the key; test harnesses reusing a trimmed-down config; deployments that assumed the tool works allow-all by default.
Related errors
- Host '{host}' is not in http_request.allowed_domains
- Blocked local/private host: {host}
- auth_secret requires a config.toml path
- environment-backed auth_secret references an empty environme
- model_provider `{ref_or_family}` does not resolve to a confi
AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23).
Data as JSON: /api/errors/d4ed8ad1364e8dd3.
Report an issue: GitHub.