tonhowtf/omniget · error

Connection to relay timed out (10s)

Error message

Connection to relay timed out (10s)

What it means

connect_relay dials the P2P relay address (relay_addr()) wrapped in a 10-second tokio::time::timeout around TcpStream::connect. When the timeout elapses before the TCP connection completes, the elapsed error is mapped to this message. It means the relay host was unreachable (or too slow) within 10 seconds; a failed connect that returns promptly is instead reported as 'Failed to connect to relay ...'.

Solutions

  1. Verify the relay is running and reachable: `nc -vz <host> <port>` against the address from relay_addr().
  2. Check relay_addr() configuration — wrong host/port is the most common cause of connect timeouts rather than refused connections.
  3. Test from the same network without firewall/VPN to rule out blocked egress on the relay port.
  4. Increase the 10s timeout if the relay is known to be slow, or add retry with backoff for transient network issues.
  5. Surface a user-facing 'relay unreachable' state and fall back to non-relay transfer if applicable.

Example fix

// before
let stream = tokio::time::timeout(
    std::time::Duration::from_secs(10),
    TcpStream::connect(&addr),
).await.map_err(|_| anyhow!("Connection to relay timed out (10s)"))?...
// after
const RELAY_TIMEOUT: Duration = Duration::from_secs(10);
let mut attempt = 0;
let stream = loop {
    attempt += 1;
    match tokio::time::timeout(RELAY_TIMEOUT, TcpStream::connect(&addr)).await {
        Ok(res) => break res.map_err(|e| anyhow!("Failed to connect to relay {}: {}", addr, e))?,
        Err(_) if attempt < 3 => tokio::time::sleep(Duration::from_secs(2 * attempt)).await,
        Err(_) => return Err(anyhow!("Connection to relay {} timed out after {} attempts", addr, attempt)),
    }
};
Defensive patterns

Strategy: retry

Validate before calling

// Rust: probe relay reachability before starting a relay-based transfer
async fn relay_reachable() -> bool {
    let addr = relay_addr();
    tokio::time::timeout(Duration::from_secs(3), TcpStream::connect(&addr))
        .await
        .map(|r| r.is_ok())
        .unwrap_or(false)
}

Try / catch

match p2p_download(opts).await {
    Err(e) if e.to_string().contains("Connection to relay timed out") => {
        // relay unreachable; retry with backoff or switch to direct/LAN transfer
        tokio::time::sleep(Duration::from_secs(5)).await;
        p2p_download(opts).await
    }
    other => other,
}

Prevention

When it happens

Trigger: Calling download or run_sender (the two connect_relay callers) while the relay at relay_addr() is down, firewalled, DNS-resolving to a blackhole address, or the network path drops SYN packets so connect never completes within 10s.

Common situations: Relay server not running or restarted; wrong host/port in configuration (relay_addr()); corporate/NAT firewall blocking the relay port; IPv6 address attempted but unroutable, causing silent packet drop; relay under overload accepting connections slowly.

Understand the failure class

Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.

Related errors


AI-assisted analysis of tonhowtf/omniget@8600b91f42 (2026-09-12). Data as JSON: /api/errors/f2e801c5f9ccd257. Report an issue: GitHub.

Appendix: source

Thrown at src-tauri/omniget-core/src/platforms/p2p.rs:29

use tokio_util::sync::CancellationToken;

use crate::models::media::{DownloadOptions, DownloadResult, MediaInfo, MediaType, VideoQuality};
use crate::platforms::traits::PlatformDownloader;

const CHUNK_SIZE: usize = 64 * 1024;

fn relay_addr() -> String {
    std::env::var("OMNIGET_RELAY").unwrap_or_else(|_| "relay.tonho.wtf:9009".to_string())
}

async fn connect_relay() -> anyhow::Result<TcpStream> {
    let addr = relay_addr();
    let stream = tokio::time::timeout(
        std::time::Duration::from_secs(10),
        TcpStream::connect(&addr),
    )
    .await
    .map_err(|_| anyhow!("Connection to relay timed out (10s)"))?
    .map_err(|e| anyhow!("Failed to connect to relay {}: {}", addr, e))?;
    Ok(stream)
}

async fn read_line(
    reader: &mut BufReader<tokio::io::ReadHalf<TcpStream>>,
) -> anyhow::Result<String> {
    let mut line = String::new();
    let n = reader.read_line(&mut line).await?;
    if n == 0 {
        anyhow::bail!("Relay closed connection unexpectedly");
    }
    Ok(line.trim_end().to_string())
}

fn check_relay_error(line: &str) -> anyhow::Result<()> {
    if let Some(err) = line.strip_prefix("ERROR ") {
        anyhow::bail!("Relay error: {}", err);

View on GitHub (pinned to 8600b91f42)