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 60-second tokio timeout wrapping the response read expired: the peer neither sent a response nor closed the stream. The transport connection is fine, but the peer's sync handler is stuck (blocked on a lock or a very long database operation) or traffic is black-holed by a NAT or relay path. Note the timeout wraps the whole read, so a very slow large response also trips it.

Source

Thrown at core/src/service/network/transports/sync.rs:299

				.await
				.map_err(|e| 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

  1. Check peer health and its logs: a silently unresponsive peer is usually stuck, not slow
  2. Retry with backoff; a second consecutive timeout on an idle peer confirms it is unavailable
  3. For bulk sync, raise the timeout or move to a streamed job protocol so progress is visible instead of one 60s-capped response
  4. Keep individual request payloads small so responses complete well under the cap
Defensive patterns

Strategy: retry

Validate before calling

// Check peer responsiveness before committing to a long exchange
if !transport.is_device_reachable(target_device).await {
    return Ok(None);
}

Try / catch

match transport.send_sync_request(target, request).await {
    Err(e) if e.to_string().contains("timed out after 60s") => {
        // peer hung: back off, verify peer health, retry a bounded number of times
    }
    other => other,
}

Prevention

When it happens

Trigger: Peer handler deadlocks on a contended lock while processing the request; initial sync of a huge dataset where the peer needs more than 60s to assemble the response; a relay or NAT path silently dropping packets so no data or FIN ever arrives.

Common situations: First sync after pairing two large libraries; peers on mobile or unstable networks; a peer suspended by the OS while holding the sync handler.

Understand the failure class

Related errors


AI-assisted analysis of spacedriveapp/spacedrive@6dfeccf211 (2026-08-16). Data as JSON: /api/errors/003ce1cec015190e. Report an issue: GitHub.