spacedriveapp/spacedrive · error · anyhow::Error
Transfer interrupted: received {} of {} bytes before connect
Error message
Transfer interrupted: received {} of {} bytes before connection closed What it means
After the PULL receive loop exits, transfer_completed is still false: the connection closed before the sender's TransferComplete message arrived. The error reports bytes received versus the expected file_size, deletes the partial file, and fails the job. This is the signature of a mid-transfer disconnect rather than a protocol violation.
Source
Thrown at core/src/ops/files/copy/strategy.rs:740
}
crate::service::network::protocol::file_transfer::FileTransferMessage::TransferError {
message,
..
} => {
// Clean up partial file
let _ = fs::remove_file(&final_dest_path).await;
return Err(anyhow::anyhow!("Transfer error: {}", message));
}
_ => {
debug!("Received unexpected message during PULL transfer");
}
}
}
// Verify transfer completed properly
if !transfer_completed {
let _ = fs::remove_file(&final_dest_path).await;
return Err(anyhow::anyhow!(
"Transfer interrupted: received {} of {} bytes before connection closed",
total_bytes_received,
file_size
));
}
file.flush().await?;
file.sync_all().await?;
info!(
"PULL transfer completed: {} bytes from device:{} to {}",
total_bytes_received,
source_device_slug,
final_dest_path.display()
);
ctx.log(format!(
"PULL transfer completed successfully: {} bytes from device:{} to {}",View on GitHub (pinned to 6dfeccf211)
Solutions
- Retry the copy job - the transfer protocol tracks chunk state per session and restarts cleanly
- Confirm both devices are online and reachable (same network or relay reachable)
- Check the peer daemon for restarts, OOM kills, or panics at the failure timestamp
- For flaky links, disable device sleep and prefer wired connections for large files
Defensive patterns
Strategy: retry
Validate before calling
// Pre-flight: confirm the source device is present in the registry before a large PULL.
let networking = ctx.networking_service().context("networking required")?;
let registry = networking.device_registry().read().await;
if registry.get_node_by_device(source_device_id).is_none() {
anyhow::bail!("source device {} not online; defer the copy", source_device_id);
} Try / catch
let mut attempt = 0;
loop {
attempt += 1;
match run_pull_copy().await {
Ok(v) => break Ok(v),
Err(ref e) if e.to_string().starts_with("Transfer interrupted") && attempt < 3 => {
tokio::time::sleep(std::time::Duration::from_secs(2 * attempt as u64)).await;
}
Err(e) => break Err(e),
}
} Prevention
- Keep both devices awake and on a stable network during transfers
- Rely on job resumability - rerun the job instead of salvaging partial files
- Watch peer daemon health during long transfers
When it happens
Trigger: Network drop (Wi-Fi to VPN switch, sleep), remote daemon restart or crash, relay timeout, or the peer device suspending while streaming chunks - the message loop ends without TransferComplete and the guard at strategy.rs:740 fires.
Common situations: Laptop sleep during large transfers, unstable Wi-Fi, router/NAT renewal breaking the QUIC path, remote device rebooting for updates mid-copy.
Understand the failure class
- Connection failures: ECONNREFUSED, ECONNRESET, and friends — why connections get refused, reset, or dropped.
Related errors
- Transfer error: {}
- Could not find node_id for device {}
- Failed to open stream: {}
- Failed to write message length: {}
- Failed to write chunk data: {}
AI-assisted analysis of spacedriveapp/spacedrive@6dfeccf211 (2026-08-16).
Data as JSON: /api/errors/2b83c2e403594c58.
Report an issue: GitHub.