spacedriveapp/spacedrive · error · anyhow::Error

Failed to finish stream: {}

Error message

Failed to finish stream: {}

What it means

After all chunks and the completion message were sent, send_stream.finish() failed - the QUIC FIN could not be queued because the connection broke in the window after the last flush. The transfer outcome is now unknown: the receiver may hold all data but never saw a clean end-of-stream. The sender fails the job rather than assume success.

Source

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

			total_bytes: bytes_transferred,
		};

	let completion_data = rmp_serde::to_vec(&completion_message)?;

	send_stream.write_u8(0).await?;
	send_stream
		.write_all(&(completion_data.len() as u32).to_be_bytes())
		.await?;
	send_stream.write_all(&completion_data).await?;
	send_stream.flush().await?;

	ctx.log(format!(
		"Completion message sent, waiting for final acknowledgment from receiver"
	));

	send_stream
		.finish()
		.map_err(|e| anyhow::anyhow!("Failed to finish stream: {}", e))?;

	ctx.log("Waiting for TransferFinalAck from receiver...".to_string());

	let mut msg_type = [0u8; 1];
	recv_stream.read_exact(&mut msg_type).await?;

	if msg_type[0] != 0 {
		return Err(anyhow::anyhow!("Unexpected response type: {}", msg_type[0]));
	}

	let mut len_buf = [0u8; 4];
	recv_stream.read_exact(&mut len_buf).await?;
	let msg_len = u32::from_be_bytes(len_buf) as usize;

	let mut msg_buf = vec![0u8; msg_len];
	recv_stream.read_exact(&mut msg_buf).await?;

	let ack_message: crate::service::network::protocol::file_transfer::FileTransferMessage =

View on GitHub (pinned to 6dfeccf211)

Solutions

  1. Retry the copy - the receiver discards an unfinished stream on its side
  2. Check the peer for crashes or resource pressure while processing the completion message
  3. If it recurs at the very end of large transfers, check peer memory and disk pressure
  4. Verify network stability across the full transfer duration
Defensive patterns

Strategy: retry

Try / catch

// finish() failure means unknown outcome; only a full retry can confirm delivery.
match complete_transfer().await {
    Ok(()) => Ok(()),
    Err(ref e) if e.to_string().contains("finish") => {
        tracing::warn!(error = %e, "stream FIN failed; receiver will discard, retrying");
        complete_transfer().await
    }
    Err(e) => Err(e.clone()),
}

Prevention

When it happens

Trigger: Connection dropped immediately after the completion message was flushed; peer reset the connection upon receiving it; network change between the final write and finish().

Common situations: Last-instant disconnects at the end of long transfers, peer crashing while handling the completion message.

Related errors


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