nautechsystems/nautilus_trader · error
{description} endpoint must use HTTPS or canonical loopback
Error message
{description} endpoint must use HTTPS or canonical loopback HTTP What it means
Thrown by `validate_execution_endpoint` when the URL parses but its scheme is neither `http` nor `https`. The adapter only speaks HTTP(S) JSON-RPC, so schemes like `ws`, `ftp`, or `file` are rejected outright.
Source
Thrown at crates/adapters/blockchain/src/rpc/http.rs:918
}
let hex_string = parsed
.result
.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)
}
View on GitHub (pinned to 18893faf8b)
Solutions
- Convert the endpoint to HTTPS: replace `wss://` with `https://` if the server also serves HTTP JSON-RPC.
- Use `http://` only for canonical loopback addresses (127.0.0.1, [::1]) in local development.
- Check that the config field expects an execution (HTTP) endpoint and not a separate websocket field.
Example fix
// before let endpoint = "wss://mainnet.infura.io/ws/v3/KEY"; // websocket scheme rejected // after let endpoint = "https://mainnet.infura.io/v3/KEY";
Defensive patterns
Strategy: validation
Validate before calling
let url = url::Url::parse(endpoint).map_err(|e| anyhow::anyhow!("invalid endpoint: {e}"))?;
anyhow::ensure!(matches!(url.scheme(), "http" | "https"),
"endpoint must be http(s), got '{}'", url.scheme()); Type guard
fn is_http_scheme(s: &str) -> bool {
url::Url::parse(s).map(|u| matches!(u.scheme(), "http" | "https")).unwrap_or(false)
} Try / catch
match HttpRpcClient::new(ws_endpoint) {
Err(e) if e.to_string().contains("must use HTTPS or canonical loopback HTTP") => {
// config field got a ws:// URL; surface a targeted config error
return Err(anyhow::anyhow!("HTTP client requires an http(s) endpoint, not a websocket URL"));
}
other => other,
} Prevention
- Keep websocket and HTTP endpoint config fields separate; never reuse a wss:// URL in an HTTP field.
- Convert wss:// provider URLs to their https:// JSON-RPC equivalent when switching clients.
- Validate scheme at config-load time.
When it happens
Trigger: Supplying an endpoint with a non-HTTP scheme to `new`, `normalize_endpoint`, or the validation helpers — commonly a WebSocket endpoint (`ws://`/`wss://`) pasted into an HTTP execution-endpoint config field.
Common situations: Reusing a websocket RPC URL from another client/library in an HTTP-only config; typo'd scheme (`htps://` fails earlier, but `ws://` reaches this check); internal conventions like `unix://` sockets.
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
- Invalid {description} endpoint
- {description} endpoint host is required
- {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/4668d9a75b1b438f.
Report an issue: GitHub.