rathole-org/rathole · error
No available data channels
Error message
No available data channels
What it means
run_udp_connection_pool pulls a ready data channel from an internal mpsc channel to forward UDP traffic. If the channel is closed (all senders dropped) or empty when `recv().await` completes, it means no data channels were established, so UDP forwarding cannot proceed and the error is raised at src/server.rs:687.
Solutions
- Ensure the client is running and successfully establishes data channels before/in tandem with UDP traffic.
- Check logs on the client side for data-channel connection failures (TLS/noise/websocket handshake errors).
- Verify network/firewall rules allow the data channel connections between client and server.
- Reconnect the client or restart the UDP session so the pool gets a fresh data channel.
Defensive patterns
Strategy: retry
Try / catch
match run_udp_connection_pool(...).await {
Err(e) if e.to_string().contains("No available data channels") => {
warn!("data channel pool empty; retrying after reconnect");
tokio::time::sleep(Duration::from_secs(2)).await;
// re-establish data channels then retry
}
other => other?,
} Prevention
- Ensure the client maintains enough data channels before opening UDP sessions
- Add health checks that data channels are alive
- Handle client disconnects by tearing down dependent UDP sessions
When it happens
Trigger: A UDP session is requested on the server but the pool's data_ch_rx receiver yields None — typically because no client-side data channels connected yet, or all data channel tasks exited/closed the channel.
Common situations: Client disconnected while a UDP session (e.g. DNS forwarding) is still active; network interruption killed all data channel connections; server started but no client ever established the data channel pool; firewall/NAT blocking the data channel connections.
Understand the failure class
Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.
Related errors
- Expect UDP traffic. Please check the configuration.
- Unexpected type of hello
- Protocol version mismatched. Expected
- Failed to lookup the host
AI-assisted analysis of rathole-org/rathole@a292f7ed54 (2026-09-07).
Data as JSON: /api/errors/34f2a1abb6a28649.
Report an issue: GitHub.
Appendix: source
Thrown at src/server.rs:687
listen_backoff(),
|| async { Ok(UdpSocket::bind(&bind_addr).await?) },
|e, duration| {
warn!("{:#}. Retry in {:?}", e, duration);
},
&mut shutdown_rx,
)
.await
.with_context(|| "Failed to listen for the service")?;
info!("Listening at {}", &bind_addr);
let cmd = bincode::serialize(&DataChannelCmd::StartForwardUdp).unwrap();
// Receive one data channel
let mut conn = data_ch_rx
.recv()
.await
.ok_or_else(|| anyhow!("No available data channels"))?;
write_and_flush(&mut conn, &cmd).await?;
let mut buf = [0u8; UDP_BUFFER_SIZE];
loop {
tokio::select! {
// Forward inbound traffic to the client
val = l.recv_from(&mut buf) => {
let (n, from) = val?;
UdpTraffic::write_slice(&mut conn, from, &buf[..n]).await?;
},
// Forward outbound traffic from the client to the visitor
hdr_len = conn.read_u8() => {
let t = UdpTraffic::read(&mut conn, hdr_len?).await?;
l.send_to(&t.data, t.from).await?;
}
_ = shutdown_rx.recv() => {View on GitHub (pinned to a292f7ed54)