n0-computer/iroh · error · RelayUrlParseError

RelayUrlParseError

RelayUrlParseError

Error message

Failed to parse relay URL

What it means

This is a sentinel wrapper error type (`RelayUrlParseError`) raised by `RelayUrl::from_str` when the input string cannot be parsed as a valid URL by the `url` crate (`Url::from_str` fails with a `url::ParseError`, e.g. missing scheme, invalid characters, or a malformed host). The faulting input is the string being parsed into a `RelayUrl`; it must be an absolute URL such as `https://relay.example.com/` to succeed.

Solutions

  1. Fix the URL string so it is a fully qualified valid URL, e.g. "https://relay.example.com".
  2. Validate with url::Url::parse first to get a detailed parse-error message.
  3. Check config/env sources for typos, whitespace, or missing scheme.
  4. Build the RelayUrl from a validated Url (RelayUrl::from) if you need custom control.

Example fix

// before
let relay: RelayUrl = "relay.example.com".parse()?; // missing scheme
// after
let relay: RelayUrl = "https://relay.example.com".parse()?;
Defensive patterns

Strategy: validation

Validate before calling

fn parse_relay_url(s: &str) -> Result<RelayUrl, url::ParseError> {
    let u = url::Url::parse(s)?;
    Ok(RelayUrl::from(u))
}

Type guard

fn is_parseable_url(s: &str) -> bool { url::Url::parse(s).is_ok() }

Try / catch

match s.parse::<RelayUrl>() {
    Err(RelayUrlParseError(e)) => bail!("bad relay url '{s}': {e}"),
    Ok(u) => u,
}

Prevention

When it happens

Trigger: Calling "...".parse::<RelayUrl>() or RelayUrl::from_str with a malformed URL string (missing scheme, invalid characters, unparseable host) that the url crate's parser rejects.

Common situations: Relay addresses in config files or env vars with typos or missing https:// prefix, user-supplied relay URLs from CLI args, trimmed/whitespace-corrupted values, IPv6 hosts without brackets.

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 n0-computer/iroh@2b4de030ce (2026-09-08). Data as JSON: /api/errors/06d6b7a8d7676d67. Report an issue: GitHub.

Appendix: source

Thrown at iroh-base/src/relay_url.rs:32

/// It is encouraged to use a fully-qualified DNS domain name in the URL.  Meaning a DNS
/// name which ends in a `.`, e.g, in `relay.example.com.`.  Otherwise the DNS resolution of
/// your local host or network could interpret the DNS name as relative and in some
/// configurations might cause additional delays or even connection problems.
#[derive(
    Clone, derive_more::Display, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize,
)]
pub struct RelayUrl(Arc<Url>);

impl From<Url> for RelayUrl {
    fn from(url: Url) -> Self {
        Self(Arc::new(url))
    }
}

/// Can occur when parsing a string into a [`RelayUrl`].
#[stack_error(derive, add_meta)]
#[error("Failed to parse relay URL")]
pub struct RelayUrlParseError(#[error(std_err)] url::ParseError);

/// Support for parsing strings directly.
///
/// If you need more control over the error first create a [`Url`] and use [`RelayUrl::from`]
/// instead.
impl FromStr for RelayUrl {
    type Err = RelayUrlParseError;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        let inner = Url::from_str(s).map_err(RelayUrlParseError::new)?;
        Ok(RelayUrl::from(inner))
    }
}

impl From<RelayUrl> for Url {
    fn from(value: RelayUrl) -> Self {
        Arc::unwrap_or_clone(value.0)
    }

View on GitHub (pinned to 2b4de030ce)