nautechsystems/nautilus_trader · error

Invalid {description} endpoint

Error message

Invalid {description} endpoint

What it means

Thrown by `validate_execution_endpoint` when the endpoint string cannot be parsed as a URL at all. This is the first gate in endpoint validation: before scheme/host/loopback checks, the value must be a well-formed URL. The `description` placeholder names the endpoint's role (e.g. "execution").

Source

Thrown at crates/adapters/blockchain/src/rpc/http.rs:917

            return Err(BroadcastError::Rejected { code: error.code });
        }

        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

  1. Add an explicit scheme: `https://host:port` (or `http://127.0.0.1:8545` for loopback).
  2. Trim whitespace/quotes from the configured endpoint value in your env/config source.
  3. Print `Url::parse(endpoint)` in a quick REPL/test to see which part of the string is malformed.
  4. Use `normalize_endpoint` to canonicalize before validation where available.

Example fix

// before
let endpoint = "my-node.internal:8545"; // no scheme -> Url::parse fails
// after
let endpoint = "https://my-node.internal:8545";
Defensive patterns

Strategy: validation

Validate before calling

fn assert_valid_http_url(s: &str) -> Result<(), String> {
    let url = url::Url::parse(s).map_err(|e| format!("not a URL: {e}"))?;
    match url.scheme() {
        "http" | "https" => Ok(()),
        other => Err(format!("scheme {other} not http/https")),
    }
}
// call before constructing the client: assert_valid_http_url(&endpoint).unwrap();

Type guard

fn is_http_url(s: &str) -> bool {
    url::Url::parse(s).map(|u| matches!(u.scheme(), "http" | "https")).unwrap_or(false)
}

Try / catch

let client = HttpRpcClient::new(&endpoint).map_err(|e| {
    anyhow::anyhow!("bad execution endpoint '{endpoint}': {e}")
})?;

Prevention

When it happens

Trigger: Passing a string that `Url::parse` rejects to `new`, `normalize_endpoint`, or the endpoint-validation tests — e.g. missing scheme ("localhost:8545" is parsed as scheme-only and fails expectations, "node.internal:8545"), stray characters, or an empty string.

Common situations: Config/env var set without the `http://` or `https://` prefix; copy-pasted endpoint with quotes, spaces, or trailing slashes/garbage; using a Unix-socket style path instead of an http URL.

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


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/4dd0f125bfe0a4de. Report an issue: GitHub.