Hmbown/CodeWhale · error · anyhow::Error
Refusing insecure base URL
Error message
Refusing insecure base URL '{display_base_url}'.
Loopback hosts (localhost, 127.0.0.1, [::1]) are auto-allowed.
For one trusted local provider (LAN, llama.cpp on a private IP, etc.) set
`allow_insecure_http = true` under its `[providers.<name>]` table in config.toml.
To allow it for every provider in this shell instead, set the env var
`{ALLOW_INSECURE_HTTP_ENV}=1` and re-run. What it means
The HTTP client refuses to connect to a provider whose base URL uses plain http:// on a non-loopback host. Loopback hosts (localhost, 127.0.0.1, [::1]) are auto-allowed; anything else would send prompts and API keys in cleartext, so startup fails with this message explaining the three opt-in mechanisms. It is a deliberate security guard against credential leakage over unencrypted LAN traffic.
Solutions
- Use https:// for the provider base URL (preferred fix).
- Use a loopback host (localhost / 127.0.0.1) with a port-forward or tunnel so the auto-allow applies.
- Set `allow_insecure_http = true` under the specific `[providers.<name>]` table in config.toml for that one trusted provider.
- Set the ALLOW_INSECURE_HTTP_ENV env var to 1 to allow insecure HTTP for every provider in this shell (broadest, least safe).
Example fix
// config.toml — before [providers.llamacpp] base_url = "http://192.168.1.50:8080" // after [providers.llamacpp] base_url = "http://192.168.1.50:8080" allow_insecure_http = true
Defensive patterns
Strategy: validation
Validate before calling
let url = url::Url::parse(&base_url)?;
let insecure = url.scheme() == "http"
&& !matches!(url.host_str(), Some("localhost") | Some(h) if h.parse::<std::net::IpAddr>().map(|i| i.is_loopback()).unwrap_or(false));
if insecure && !provider_allow_insecure_http && std::env::var("CODEWHALE_ALLOW_INSECURE_HTTP") != Ok("1".into()) {
// switch to https / loopback, or set the opt-in before startup
} Try / catch
match build_client(&provider) {
Ok(c) => c,
Err(e) if e.to_string().contains("Refusing insecure base URL") => {
eprintln!("{e}"); // the message lists the exact opt-in options
std::process::exit(2);
}
Err(e) => return Err(e),
} Prevention
- Default provider base URLs to https:// and only use http for loopback hosts.
- For LAN model servers, tunnel over SSH (localhost forward) instead of allowing insecure HTTP.
- Scope any insecure-HTTP opt-in to a single provider table rather than the global env var.
- Double-check scheme typos (http vs https) when configuring local providers.
When it happens
Trigger: Configuring a provider with an http:// base URL pointing at a LAN/private-IP host (e.g. http://192.168.1.50:8080) and starting a session, without any insecure-HTTP opt-in.
Common situations: Pointing Codewhale at a local llama.cpp/Ollama/LM Studio instance by its LAN IP; docker/VM setups where the model server is reachable only via a private address; typo-ing https:// as http://.
Understand the failure class
Background: "Invalid URL" / "URL cannot be empty": fix the malformed or missing URL behind request-construction failures — this error's family across 50 libraries.
Related errors
- bundle redirects may not change URL scheme
- Refusing insecure base URL
- The update service exceeded its response size limit.
- building bundle fetch client failed
- bundle fetch failed with HTTP status
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/49827fd94a308e27.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/client.rs:1112
);
return Ok(());
}
if parsed.scheme() == "http"
&& std::env::var(ALLOW_INSECURE_HTTP_ENV)
.or_else(|_| std::env::var(LEGACY_ALLOW_INSECURE_HTTP_ENV))
.ok()
.as_deref()
.is_some_and(|v| v == "1" || v.eq_ignore_ascii_case("true"))
{
logging::warn(format!(
"Using insecure HTTP base URL because {ALLOW_INSECURE_HTTP_ENV} is set"
));
return Ok(());
}
if parsed.scheme() == "http" {
anyhow::bail!(
"Refusing insecure base URL '{display_base_url}'.\n\
\n\
Loopback hosts (localhost, 127.0.0.1, [::1]) are auto-allowed.\n\
For one trusted local provider (LAN, llama.cpp on a private IP, etc.) set\n\
`allow_insecure_http = true` under its `[providers.<name>]` table in config.toml.\n\
To allow it for every provider in this shell instead, set the env var\n\
`{ALLOW_INSECURE_HTTP_ENV}=1` and re-run.",
);
}
anyhow::bail!(
"Refusing base URL '{display_base_url}': only HTTPS (or explicitly allowed HTTP) URLs are supported.",
)
}
/// Mask credentials in a URL for display.
///
/// Delegates to the single shared implementation inView on GitHub (pinned to 73e0f67d83)