rathole-org/rathole · error

proxy url should have port field

Error message

proxy url should have port field

What it means

A generic validation panic in tcp_connect_with_proxy: a proxy URL was supplied (socks5:// or http://) but the parsed Url has no port, so url.port() returns None and expect() aborts. The input at fault is the proxy option whose URL lacks an explicit port; the helper requires host and port to open the TCP connection to the proxy itself.

Solutions

  1. Specify an explicit port in the proxy URL, e.g. http://127.0.0.1:8080 or socks5://user:pass@host:1080
  2. Pre-validate the proxy URL in config parsing (reject proxies without a port before startup)
  3. Use url.port_or_known_default() to fall back to scheme defaults instead of expect
  4. Document the port requirement for the --proxy option
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at src/helper.rs:119 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of rathole-org/rathole@a292f7ed54 (2026-09-07). Data as JSON: /api/errors/b37e57a76ba58bc4. Report an issue: GitHub.

Appendix: source

Thrown at src/helper.rs:119

        }
    };
    let s = UdpSocket::bind(bind_addr).await?;
    s.connect(socket_addr).await?;
    s.connect(socket_addr).await?;
    Ok(s)
}

/// Create a TcpStream using a proxy
/// e.g. socks5://user:pass@127.0.0.1:1080 http://127.0.0.1:8080
pub async fn tcp_connect_with_proxy(
    addr: &AddrMaybeCached,
    proxy: Option<&Url>,
) -> Result<TcpStream> {
    if let Some(url) = proxy {
        let addr = &addr.addr;
        let mut s = TcpStream::connect((
            url.host_str().expect("proxy url should have host field"),
            url.port().expect("proxy url should have port field"),
        ))
        .await?;

        let auth = if !url.username().is_empty() || url.password().is_some() {
            Some(async_socks5::Auth {
                username: url.username().into(),
                password: url.password().unwrap_or("").into(),
            })
        } else {
            None
        };
        match url.scheme() {
            "socks5" => {
                async_socks5::connect(&mut s, host_port_pair(addr)?, auth).await?;
            }
            "http" => {
                let (host, port) = host_port_pair(addr)?;
                match auth {

View on GitHub (pinned to a292f7ed54)