rustdesk/rustdesk-server · error

Timeout of test_hbbs

Error message

Timeout of test_hbbs

What it means

This is a self-test watchdog inside hbbs: when the server runs in test mode (test_hbbs, started by start_with_bind), it waits for a parsed RendezvousMessage on its socket; if nothing arrives for more than 12 seconds, it bails with "Timeout of test_hbbs", ending the self-test. It exists so a broken server loop fails fast instead of hanging forever.

Solutions

  1. Ensure the test client sends a valid, current-protocol RendezvousMessage promptly (well under 12s) after the server starts.
  2. Check loopback networking/firewall rules so the test packet can reach the bound socket.
  3. Enable trace logging (log::trace shows 'Recv ... of test_hbbs') to see whether messages arrive but fail to parse.
  4. If the test legitimately needs longer, increase the 12-second threshold in src/rendezvous_server.rs.

Example fix

// test harness: send the probe message immediately, with retry
let mut attempts = 0;
while attempts < 3 {
    socket.send(&msg, addr).await.ok();
    if socket.recv_timeout(Duration::from_secs(2)).is_ok() { break; }
    attempts += 1;
}
Defensive patterns

Strategy: try-catch

Validate before calling

// CI: verify the probe message parses with the same protocol version before starting the test
let _ = RendezvousMessage::parse_from_bytes(&probe_bytes).expect("probe must parse");

Try / catch

// wrap the self-test runner with a timeout-tolerant wrapper
match tokio::time::timeout(Duration::from_secs(20), test_hbbs()).await {
    Err(_) => log::warn!("test_hbbs watchdog fired (12s no-reply)"),
    Ok(Err(e)) => log::error!("test_hbbs failed: {e}"),
    Ok(Ok(())) => log::info!("test_hbbs passed"),
}

Prevention

When it happens

Trigger: Running hbbs in test_hbbs mode and the local socket receives no parseable RendezvousMessage within 12 seconds - either the test client never sent a message, the packet was corrupt (parse_from_bytes failed), or the server loop is stuck.

Common situations: CI smoke tests of hbbs where the test client is slow to start or sends a malformed message; firewall/loopback issues preventing the test packet from arriving; protocol changes between test client and server breaking parse_from_bytes.

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 rustdesk/rustdesk-server@a7736be5e4 (2026-09-09). Data as JSON: /api/errors/8f2f20fcf43cd181. Report an issue: GitHub.

Appendix: source

Thrown at src/rendezvous_server.rs:1356

        } else {
            IpAddr::V6(Ipv6Addr::LOCALHOST)
        });
    }

    let mut socket = FramedSocket::new(config::Config::get_any_listen_addr(addr.is_ipv4())).await?;
    let mut msg_out = RendezvousMessage::new();
    msg_out.set_register_peer(RegisterPeer {
        id: "(:test_hbbs:)".to_owned(),
        ..Default::default()
    });
    let mut last_time_recv = Instant::now();

    let mut timer = interval(Duration::from_secs(1));
    loop {
        tokio::select! {
          _ = timer.tick() => {
              if last_time_recv.elapsed().as_secs() > 12 {
                  bail!("Timeout of test_hbbs");
              }
              socket.send(&msg_out, addr).await?;
          }
          Some(Ok((bytes, _))) = socket.next() => {
              if let Ok(msg_in) = RendezvousMessage::parse_from_bytes(&bytes) {
                 log::trace!("Recv {:?} of test_hbbs", msg_in);
                 last_time_recv = Instant::now();
              }
          }
        }
    }
}

#[inline]
async fn send_rk_res(
    socket: &mut FramedSocket,
    addr: SocketAddr,
    res: register_pk_response::Result,

View on GitHub (pinned to a7736be5e4)