nautechsystems/nautilus_trader · error
{description} endpoint host is required
Error message
{description} endpoint host is required What it means
Thrown by `validate_execution_endpoint` when the parsed URL has no host component. An HTTP JSON-RPC endpoint must address a host, so scheme-only or opaque URLs (e.g. `http:` with nothing after it, or `mailto:`-like forms) fail this check.
Source
Thrown at crates/adapters/blockchain/src/rpc/http.rs:922
.ok_or_else(|| BroadcastError::Failed("Broadcast returned no result".to_string()))?;
B256::from_str(&hex_string)
.map_err(|e| BroadcastError::Failed(format!("Failed to parse broadcast result: {e}")))
}
}
#[cfg(feature = "hypersync")]
pub(crate) fn validate_execution_endpoint(
endpoint: &str,
description: &str,
) -> anyhow::Result<Url> {
let url =
Url::parse(endpoint).map_err(|_| anyhow::anyhow!("Invalid {description} endpoint"))?;
anyhow::ensure!(
matches!(url.scheme(), "http" | "https"),
"{description} endpoint must use HTTPS or canonical loopback HTTP"
);
anyhow::ensure!(
url.host().is_some(),
"{description} endpoint host is required"
);
anyhow::ensure!(
url.fragment().is_none(),
"{description} endpoint fragments are unsupported"
);
anyhow::ensure!(
url.scheme() == "https" || is_canonical_loopback_endpoint(endpoint),
"{description} endpoint must use HTTPS unless its host is a canonical loopback IP literal"
);
Ok(url)
}
fn is_canonical_loopback_endpoint(endpoint: &str) -> bool {
let Some((scheme, rest)) = endpoint.split_once("://") else {
return false;
};View on GitHub (pinned to 18893faf8b)
Solutions
- Ensure the configured value includes a host: `https://your-node.example.com:8545`.
- Check that environment variable/templating substitution actually populated the host part.
- Validate the endpoint string at startup (fail fast) rather than at first RPC call.
Example fix
// before
let endpoint = &format!("https://{}", std::env::var("RPC_HOST").unwrap_or_default()); // empty host
// after
let endpoint = &format!("https://{}", std::env::var("RPC_HOST").expect("RPC_HOST must be set")); Defensive patterns
Strategy: validation
Validate before calling
let url = url::Url::parse(endpoint)?;
anyhow::ensure!(url.host().is_some(), "endpoint is missing a host: '{endpoint}'"); Type guard
fn has_host(s: &str) -> bool {
url::Url::parse(s).map(|u| u.host().is_some()).unwrap_or(false)
} Try / catch
let endpoint = format!("https://{}", host_var); // ensure substitution happened
let client = HttpRpcClient::new(&endpoint).map_err(|e| {
if e.to_string().contains("host is required") {
anyhow::anyhow!("RPC_HOST is unset or empty; got endpoint '{endpoint}'")
} else { e.into() }
})?; Prevention
- Use expect/unwrap_or_die on env vars that build endpoint URLs so empty values fail loudly.
- Prefer whole-URL config values over string concatenation of host+path.
- Add a startup assertion that every endpoint URL has a host.
When it happens
Trigger: Passing a URL that parses but yields `url.host() == None` — e.g. `"http://"`, `"https:///path"`, or a scheme-only string — to `new`, `normalize_endpoint`, or validation tests.
Common situations: Config value partially deleted leaving `http://` behind; templating variable left empty so the URL becomes `https://${HOST}` with HOST unset; string concatenation bugs building the endpoint.
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 {description} endpoint
- {description} endpoint must use HTTPS or canonical loopback
- {description} endpoint fragments are unsupported
- request_rate_per_second must be greater than zero
- order_request_rate_per_second must be greater than zero
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/e72c265b422847fa.
Report an issue: GitHub.