spacedriveapp/spacedrive · error · anyhow::Error
Sync request timed out after 60s - peer {} not responding
Error message
Sync request timed out after 60s - peer {} not responding What it means
The tokio timeout(Duration::from_secs(60)) wrapping the entire response read elapsed. The peer accepted the connection and the request but did not deliver a complete response within 60 seconds - slow response generation on the peer, a stuck handler, or a stalled network path.
Source
Thrown at core/src/service/network/protocol/sync/transport.rs:202
anyhow::anyhow!("Failed to read response length: {}", e)
})?;
let resp_len = u32::from_be_bytes(len_buf) as usize;
debug!("Receiving sync response of {} bytes", resp_len);
let mut resp_buf = vec![0u8; resp_len];
recv.read_exact(&mut resp_buf)
.await
.map_err(|e| anyhow::anyhow!("Failed to read response: {}", e))?;
Ok::<_, anyhow::Error>(resp_buf)
})
.await;
let resp_buf = match result {
Ok(Ok(buf)) => buf,
Ok(Err(e)) => return Err(e),
Err(_) => {
return Err(anyhow::anyhow!(
"Sync request timed out after 60s - peer {} not responding",
target_device
))
}
};
// Deserialize response
let response: SyncMessage = serde_json::from_slice(&resp_buf)
.map_err(|e| anyhow::anyhow!("Failed to deserialize sync response: {}", e))?;
debug!(
device_uuid = %target_device,
response_type = ?std::mem::discriminant(&response),
"Received sync response"
);
Ok(response)
}View on GitHub (pinned to 6dfeccf211)
Solutions
- Raise the timeout or make it adaptive to library size
- Have the peer emit progress or keepalive bytes so the reader does not time out during long computations
- Profile the peer handler stage that is slow
- Retry once - transient stalls are common
Example fix
// before
let result = timeout(Duration::from_secs(60), async { /* read */ }).await;
// after
let budget = Duration::from_secs(60 + (library_size / 10_000).max(0));
let result = timeout(budget, async { /* read */ }).await; Defensive patterns
Strategy: retry
Type guard
fn is_sync_timeout(err: &anyhow::Error) -> bool {
err.to_string().contains("timed out after 60s")
} Try / catch
match net.send_sync_request(device, request).await {
Ok(resp) => { /* ... */ }
Err(e) if is_sync_timeout(&e) => {
// peer alive but slow: retry with a longer budget before giving up
tokio::time::sleep(std::time::Duration::from_secs(5)).await;
net.send_sync_request(device, request).await
}
Err(e) => Err(e),
} Prevention
- Scale the timeout with library size instead of a fixed 60s
- Have the peer send keepalive or progress bytes during long computations
- Monitor peer CPU and lock contention when timeouts cluster
When it happens
Trigger: Peer computing an expensive diff over a large library; peer handler deadlocked (for example lock contention); relay path with extreme latency; peer CPU saturated by another job.
Common situations: Initial sync of large libraries; low-power devices (phones, SBCs); peer busy with indexing or backups.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- Network endpoint not initialized
- Failed to connect to {}: {}
- Failed to open bidirectional stream: {}
- Failed to send length: {}
- Failed to send request: {}
AI-assisted analysis of spacedriveapp/spacedrive@6dfeccf211 (2026-08-16).
Data as JSON: /api/errors/4020d0d4914a6f53.
Report an issue: GitHub.