jdx/mise · error

unsupported relay destination

Error message

unsupported relay destination

What it means

The relay's request() adapter only accepts https URLs to GitHub hosts without credentials or a custom port. If the URL's scheme isn't https, carries a username/password, or specifies an explicit port, it's rejected up front with "unsupported relay destination" so the relay never proxies non-HTTPS or credentialed endpoints.

Source

Thrown at src/github_relay.rs:980

            _ = hangup.recv() => Err(crate::request_exit(129)),
            result = operation => result,
        }
    }

    /// API adapter: an HTTP request over the forwarded private socket. No upstream
    /// authentication headers are sent to the target or supplied by the target.
    pub(crate) async fn request(
        socket: &Path,
        method: Method,
        url: &Url,
        headers: &http::HeaderMap,
    ) -> Result<reqwest::Response> {
        if url.scheme() != "https"
            || !url.username().is_empty()
            || url.password().is_some()
            || url.port().is_some()
        {
            bail!("unsupported relay destination");
        }
        let prefix = match url.host_str() {
            Some("api.github.com") => "api",
            Some("github.com") => "web",
            _ => bail!("unsupported relay host"),
        };
        let mut relay_url = Url::parse(&format!("http://localhost/{prefix}{}", url.path()))?;
        relay_url.set_query(url.query());
        let (client, request_timeout) = adapter_client(socket).await?;
        let mut req = client.request(method, relay_url);
        for name in ["accept", "range", "if-range"] {
            if let Some(value) = headers.get(name) {
                req = req.header(name, value);
            }
        }
        send_adapter_request(req, request_timeout).await
    }

View on GitHub (pinned to afd2eddd3a)

Solutions

  1. Use a plain https URL with no credentials and no port, e.g. https://api.github.com/... or https://github.com/...
  2. Move credentials out of the URL into headers/auth configuration handled by the relay itself.
  3. Remove an explicit :port (443 is implied for https); if you need a nonstandard endpoint, don't route it through the relay.

Example fix

// before
let url = Url::parse("https://github.com:8443/foo/bar/releases/download/v1/a.zip")?;
// after
let url = Url::parse("https://github.com/foo/bar/releases/download/v1/a.zip")?;
Defensive patterns

Strategy: validation

Validate before calling

fn relay_supported(url: &Url) -> bool {
    url.scheme() == "https"
        && url.username().is_empty()
        && url.password().is_none()
        && url.port().is_none()
}

Prevention

When it happens

Trigger: Calling request (or code paths like adapters_use_the_brokers_timeout_policy that use it) with a URL that is http://, includes user:pass@, or has :port — e.g. an http://github.com mirror, a proxy URL with embedded credentials, or an enterprise/ghes host with a port.

Common situations: MIS-configured github enterprise endpoints with ports; HTTP fallback URLs in scripts; credentials pasted into download URLs; custom reverse-proxy hosts on nonstandard ports.

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 jdx/mise@afd2eddd3a (2026-09-09). Data as JSON: /api/errors/89f52fd6b012ba1d. Report an issue: GitHub.