spacedriveapp/spacedrive · error · anyhow::Error

Failed to connect to device: {}

Error message

Failed to connect to device: {}

What it means

execute_pull connects to the peer's iroh node with ALPN b"spacedrive/filetransfer/1" (strategy.rs:494-498). The connect fails when the node is unreachable (offline, NAT without relay, relay outage), when the peer refuses the ALPN due to an incompatible daemon version, or on timeout. The underlying iroh error string is appended for diagnosis.

Source

Thrown at core/src/ops/files/copy/strategy.rs:498

				)
			})?;
		drop(registry);

		let endpoint = networking_guard
			.endpoint()
			.ok_or_else(|| anyhow::anyhow!("Networking endpoint not available"))?;

		ctx.log(format!(
			"Opening PULL connection to node {} (device {})",
			node_id, source_device_id
		));

		// Connect to remote device
		let node_addr = iroh::EndpointAddr::new(node_id);
		let connection = endpoint
			.connect(node_addr, b"spacedrive/filetransfer/1")
			.await
			.map_err(|e| anyhow::anyhow!("Failed to connect to device: {}", e))?;

		let (mut send_stream, mut recv_stream) = connection
			.open_bi()
			.await
			.map_err(|e| anyhow::anyhow!("Failed to open bidirectional stream: {}", e))?;

		// Send PullRequest
		let transfer_id = uuid::Uuid::new_v4();
		let current_device_id = crate::device::get_current_device_id();
		// Normalize path separators to forward slashes for cross-platform transmission.
		// The receiving device may use a different OS separator (Windows \ vs Unix /).
		let normalized_source_path =
			PathBuf::from(source_path.to_string_lossy().replace('\\', "/"));
		let pull_request =
			crate::service::network::protocol::file_transfer::FileTransferMessage::PullRequest {
				transfer_id,
				source_path: normalized_source_path,
				requested_by: current_device_id,

View on GitHub (pinned to 6dfeccf211)

Solutions

  1. Confirm the peer device is online and retry the copy
  2. Inspect the appended iroh error (timeout vs refused vs no route) to target the fix
  3. Check relay configuration and firewall rules on both endpoints
  4. Ensure both devices run daemon versions agreeing on the spacedrive/filetransfer/1 protocol
Defensive patterns

Strategy: retry

Validate before calling

let online = networking.device_registry().read().await.get_node_by_device(device_id).is_some();
if !online {
    return Err(anyhow::anyhow!("peer {} not connected; connect() would fail", device_id));
}

Try / catch

let mut last = None;
for attempt in 0..3 {
    match endpoint.connect(iroh::EndpointAddr::new(node_id), alpn).await {
        Ok(c) => return Ok(c),
        Err(e) => { last = Some(e); tokio::time::sleep(Duration::from_secs(1 << attempt)).await; }
    }
}
Err(anyhow::anyhow!("connect failed after retries: {:?}", last))

Prevention

When it happens

Trigger: Peer went offline between the registry lookup and the connect attempt; firewall/NAT blocks both direct and relayed paths; ALPN refused because the peer runs an older/newer protocol version; relay infrastructure unreachable.

Common situations: Remote device asleep or powered off; cross-network transfers during relay downtime; mixed daemon versions during a rolling upgrade.

Related errors


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