{"record":{"id":"970d91c5918fb117","repo":"spacedriveapp/spacedrive","slug":"failed-to-finish-stream","errorCode":null,"errorMessage":"Failed to finish stream: {}","messagePattern":"Failed to finish stream: (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"core/src/ops/files/copy/strategy.rs","lineNumber":1278,"sourceCode":"\t\t\ttotal_bytes: bytes_transferred,\n\t\t};\n\n\tlet completion_data = rmp_serde::to_vec(&completion_message)?;\n\n\tsend_stream.write_u8(0).await?;\n\tsend_stream\n\t\t.write_all(&(completion_data.len() as u32).to_be_bytes())\n\t\t.await?;\n\tsend_stream.write_all(&completion_data).await?;\n\tsend_stream.flush().await?;\n\n\tctx.log(format!(\n\t\t\"Completion message sent, waiting for final acknowledgment from receiver\"\n\t));\n\n\tsend_stream\n\t\t.finish()\n\t\t.map_err(|e| anyhow::anyhow!(\"Failed to finish stream: {}\", e))?;\n\n\tctx.log(\"Waiting for TransferFinalAck from receiver...\".to_string());\n\n\tlet mut msg_type = [0u8; 1];\n\trecv_stream.read_exact(&mut msg_type).await?;\n\n\tif msg_type[0] != 0 {\n\t\treturn Err(anyhow::anyhow!(\"Unexpected response type: {}\", msg_type[0]));\n\t}\n\n\tlet mut len_buf = [0u8; 4];\n\trecv_stream.read_exact(&mut len_buf).await?;\n\tlet msg_len = u32::from_be_bytes(len_buf) as usize;\n\n\tlet mut msg_buf = vec![0u8; msg_len];\n\trecv_stream.read_exact(&mut msg_buf).await?;\n\n\tlet ack_message: crate::service::network::protocol::file_transfer::FileTransferMessage =","sourceCodeStart":1260,"sourceCodeEnd":1296,"githubUrl":"https://github.com/spacedriveapp/spacedrive/blob/6dfeccf2113039e35f2ce735f945e70dc3e4ea45/core/src/ops/files/copy/strategy.rs#L1260-L1296","documentation":"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.","triggerScenarios":"Connection dropped immediately after the completion message was flushed; peer reset the connection upon receiving it; network change between the final write and finish().","commonSituations":"Last-instant disconnects at the end of long transfers, peer crashing while handling the completion message.","solutions":["Retry the copy - the receiver discards an unfinished stream on its side","Check the peer for crashes or resource pressure while processing the completion message","If it recurs at the very end of large transfers, check peer memory and disk pressure","Verify network stability across the full transfer duration"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"// finish() failure means unknown outcome; only a full retry can confirm delivery.\nmatch complete_transfer().await {\n    Ok(()) => Ok(()),\n    Err(ref e) if e.to_string().contains(\"finish\") => {\n        tracing::warn!(error = %e, \"stream FIN failed; receiver will discard, retrying\");\n        complete_transfer().await\n    }\n    Err(e) => Err(e.clone()),\n}","preventionTips":["Check peer health before starting very large transfers","Treat a failed FIN as a failed transfer - never assume delivery"],"tags":["network","file-transfer","quic","acknowledgment"],"backgroundTag":null,"analyzedSha":"6dfeccf2113039e35f2ce735f945e70dc3e4ea45","analyzedAt":"2026-08-16T11:26:17.074Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}