tonhowtf/omniget · error
Failed to connect to relay
Error message
Failed to connect to relay {}: {} What it means
connect_relay surfaces the underlying OS error when TcpStream::connect to the relay fails immediately (the message interpolates the relay address and the io::Error). This is the non-timeout failure path: the connect attempt itself returned an error, e.g. connection refused, DNS resolution failure, or no route to host.
Solutions
- Read the embedded io::Error: 'refused' means start the relay service; 'resolve' means fix DNS/hostname in relay_addr().
- Confirm the relay is listening on the configured port (ss -ltn / netstat on the relay host).
- Validate relay_addr() output and correct any misconfigured host or port.
- Test connectivity manually: nc -vz <relay-host> <port>.
- Retry if the failure was transient (network flap); consider adding automatic retry in the caller.
Example fix
// before
.map_err(|e| anyhow!("Failed to connect to relay {}: {}", addr, e))?;
// after
.map_err(|e| {
tracing::error!("relay connect failed addr={} err={:?}", addr, e);
anyhow!("Failed to connect to relay {}: {} (is the relay running and reachable?)", addr, e)
})?; Defensive patterns
Strategy: retry
Validate before calling
// Rust: probe the relay endpoint before the transfer
async fn can_reach_relay(addr: &str) -> Result<(), String> {
tokio::net::TcpStream::connect(addr)
.await
.map(|_| ())
.map_err(|e| format!("relay {} unreachable: {}", addr, e))
} Try / catch
if let Err(e) = connect_relay().await {
tracing::error!("relay connect failed: {e:#}");
// parse embedded io::Error kind: ConnectionRefused -> start relay; NotFound/Resolve -> fix DNS
return Err(anyhow!("Relay unavailable, please try again later"));
} Prevention
- Run the relay under a process manager so it auto-restarts
- Validate relay_addr() config at app startup with a connectivity check
- Use IPs or verified DNS names to avoid resolution failures
- Log the io::Error kind, not just the message
When it happens
Trigger: TcpStream::connect(&addr) returns Err — relay port not listening (connection refused), hostname in relay_addr() does not resolve, or OS-level network error (no route, network unreachable).
Common situations: Relay service not started on the host; typo in relay host/port; DNS outage; connecting to localhost relay that isn't running; wrong port after a config change.
Understand the failure class
Background: ECONNREFUSED and "connection refused" / "could not connect to server" errors: what they mean and how to fix them — this error's family across 44 libraries.
Related errors
- Relay closed connection unexpectedly
- Relay closed connection unexpectedly
- Connection to relay timed out (10s)
- Failed to connect to relay
- Connection to relay timed out (10s)
AI-assisted analysis of tonhowtf/omniget@8600b91f42 (2026-09-12).
Data as JSON: /api/errors/bfdc032ab9ace71e.
Report an issue: GitHub.
Appendix: source
Thrown at src-tauri/src/platforms/p2p/mod.rs:32
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)