rathole-org/rathole · error · anyhow::Error
{}
Error message
{} What it means
Fires in the client's control-channel run loop after sending Auth(service_token-derived session key): the server replied with an Ack other than Ack::Ok (e.g. ServiceNotExist or AuthFailed). The client wraps the ack variant in a generic anyhow error, so the displayed message is the ack's Debug/Display text. It means the server rejected the control-channel establishment for this service.
Solutions
- Inspect the ack variant in the message: ServiceNotExist means the service name is unknown to the server; AuthFailed means the token does not match
- Re-check that the client's service token equals the server's token for the same service
- Confirm the service is defined in the server config and the server was reloaded after changes
- Replace the generic anyhow!("{}", v) with a typed error for clearer diagnostics
Defensive patterns
Strategy: try-catch
When it happens
Trigger: Thrown at src/client.rs:448 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/d28f8754b93a9145.
Report an issue: GitHub.
Appendix: source
Thrown at src/client.rs:448
}
};
// Send auth
debug!("Sending auth");
let mut concat = Vec::from(self.service.token.as_ref().unwrap().as_bytes());
concat.extend_from_slice(&nonce);
let session_key = protocol::digest(&concat);
let auth = Auth(session_key);
conn.write_all(&bincode::serialize(&auth).unwrap()).await?;
conn.flush().await?;
// Read ack
debug!("Reading ack");
match read_ack(&mut conn).await? {
Ack::Ok => {}
v => {
return Err(anyhow!("{}", v))
.with_context(|| format!("Authentication failed: {}", self.service.name));
}
}
// Channel ready
info!("Control channel established");
// Socket options for the data channel
let socket_opts = SocketOpts::from_client_cfg(&self.service);
let data_ch_args = Arc::new(RunDataChannelArgs {
session_key,
remote_addr,
connector: self.transport.clone(),
socket_opts,
service: self.service.clone(),
});
loop {View on GitHub (pinned to a292f7ed54)