Hmbown/CodeWhale · error
MCP HTTP requires an http:// or https:// URL with a host
Error message
MCP HTTP requires an http:// or https:// URL with a host
What it means
MCP HTTP transport only supports absolute http:// or https:// URLs that carry a host. validate_url rejects anything else (unix:, file:, ws:, or host-less URLs) before any request is made. This is a structural validation of the endpoint, separate from policy or credential checks.
Solutions
- Configure the endpoint with an absolute http:// or https:// URL including the host
- Fix the server's redirect to return an absolute Location with http(s) scheme and host
- Validate the URL string with Url::parse and check scheme/host before passing it to the client
Example fix
// before
McpHttpClient::new("example.com/mcp", ...)? // no scheme -> error
// after
McpHttpClient::new("https://example.com/mcp", ...)? Defensive patterns
Strategy: validation
Validate before calling
let u = Url::parse(endpoint).context("invalid MCP HTTP endpoint")?;
if !matches!(u.scheme(), "http" | "https") || u.host_str().is_none() {
return Err("endpoint must be absolute http(s) URL with a host");
} Type guard
fn is_valid_mcp_http_url(s: &str) -> bool {
Url::parse(s).map(|u| {
matches!(u.scheme(), "http" | "https") && u.host_str().is_some()
}).unwrap_or(false)
} Try / catch
match McpHttpClient::new(url, ...).await {
Err(e) if e.to_string().contains("requires an http:// or https:// URL") => {
// normalize: prepend scheme or reject config at load time
}
other => other?,
} Prevention
- Validate MCP endpoint strings at config-load time with Url::parse
- Require explicit scheme in config schema (reject bare host:port)
- Check redirect Location headers resolve to absolute http(s) URLs before trusting them
When it happens
Trigger: McpHttpClient::new, execute_inner (after joining a redirect Location), or client_for_target passes a URL to validate_url whose scheme is not http/https or which has no host_str — e.g. a relative redirect Location joined to a base producing a host-less URL, or an endpoint configured as "localhost/mcp" without a scheme.
Common situations: Config entry missing the scheme ("example.com/mcp"); accidental ws:// or file:// endpoint; relative or empty Location header in a redirect that joins into an invalid URL; typo like htp://.
Understand the failure class
Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.
Related errors
- Invalid MCP URL
- MCP HTTP URL must not contain credentials; use configured…
- MCP server URL ' ' must include a host
- reviewed plugin MCP endpoint has an unsafe origin
- Unsupported MCP URL
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/e06299c468b16e3e.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/mcp/http_client.rs:235
Ok(client)
}
}
fn validate_network_policy(url: &Url, network_policy: Option<&NetworkPolicyDecider>) -> Result<()> {
let host = url.host_str().context("MCP URL has no host")?;
if let Some(policy) = network_policy {
match policy.evaluate(host, "mcp") {
Decision::Allow => {}
Decision::Deny => bail!("MCP HTTP destination blocked by network policy"),
Decision::Prompt => bail!("MCP HTTP destination requires network approval"),
}
}
Ok(())
}
fn validate_url(url: &Url) -> Result<()> {
if !matches!(url.scheme(), "http" | "https") || url.host_str().is_none() {
bail!("MCP HTTP requires an http:// or https:// URL with a host");
}
Ok(())
}
fn url_has_credentials(url: &Url) -> bool {
!url.username().is_empty() || url.password().is_some()
}
impl McpHttpClient {
async fn public_dns_pin(&self, url: &Url) -> Result<Option<(String, SocketAddr)>> {
let host = url.host_str().context("MCP URL has no host")?;
let literal = host.trim_start_matches('[').trim_end_matches(']');
if let Ok(ip) = literal.parse::<IpAddr>() {
if is_restricted_ip(&ip) {
bail!("MCP HTTP destination is a restricted IP address");
}
return Ok(None);
}View on GitHub (pinned to 73e0f67d83)