{"record":{"id":"b6513d4cbe37d05c","repo":"spacedriveapp/spacedrive","slug":"final-checksum-mismatch","errorCode":null,"errorMessage":"Final checksum mismatch","messagePattern":"Final checksum mismatch","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"core/src/ops/files/copy/strategy.rs","lineNumber":711,"sourceCode":"\t\t\t\t\t\t));\n\t\t\t\t\t}\n\n\t\t\t\t\t// Verify final checksum if enabled\n\t\t\t\t\tif verify_checksum {\n\t\t\t\t\t\tif let Some(h) = hasher.take() {\n\t\t\t\t\t\t\tlet calculated = h.finalize();\n\t\t\t\t\t\t\tlet calculated_hex = calculated.to_hex().to_string();\n\n\t\t\t\t\t\t\tif final_checksum.is_empty() {\n\t\t\t\t\t\t\t\t// Warn when checksum verification enabled but no checksum provided\n\t\t\t\t\t\t\t\tctx.log(\"Warning: checksum verification enabled but remote did not provide checksum\".to_string());\n\t\t\t\t\t\t\t} else if calculated_hex != final_checksum {\n\t\t\t\t\t\t\t\terror!(\n\t\t\t\t\t\t\t\t\t\"Final checksum mismatch: expected {}, got {}\",\n\t\t\t\t\t\t\t\t\tfinal_checksum, calculated_hex\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\tlet _ = fs::remove_file(&final_dest_path).await;\n\t\t\t\t\t\t\t\treturn Err(anyhow::anyhow!(\"Final checksum mismatch\"));\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\ttransfer_completed = true;\n\t\t\t\t\tctx.log(format!(\n\t\t\t\t\t\t\"PULL transfer completed: {} bytes received\",\n\t\t\t\t\t\ttotal_bytes_received\n\t\t\t\t\t));\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcrate::service::network::protocol::file_transfer::FileTransferMessage::TransferError {\n\t\t\t\t\tmessage,\n\t\t\t\t\t..\n\t\t\t\t} => {\n\t\t\t\t\t// Clean up partial file\n\t\t\t\t\tlet _ = fs::remove_file(&final_dest_path).await;\n\t\t\t\t\treturn Err(anyhow::anyhow!(\"Transfer error: {}\", message));","sourceCodeStart":693,"sourceCodeEnd":729,"githubUrl":"https://github.com/spacedriveapp/spacedrive/blob/6dfeccf2113039e35f2ce735f945e70dc3e4ea45/core/src/ops/files/copy/strategy.rs#L693-L729","documentation":"With verify_checksum enabled, the whole-file blake3 hex of everything written did not equal the sender's final_checksum (strategy.rs:705-711). The received file is not byte-identical to what the sender hashed: the source changed during the transfer, chunks were written out of order, or versions hashed different byte ranges. The partial file is deleted. Note the code only warns when final_checksum is empty — this error requires a non-empty mismatched checksum.","triggerScenarios":"Source file modified on the peer while the pull was in flight (sender hashed before or after a change); out-of-order chunk writes; mixed versions computing checksums over different scopes.","commonSituations":"Pulling log files or actively edited documents; the same document open in an editor on the remote; mid-upgrade device fleets.","solutions":["Retry once the source file is no longer being modified on the remote","Quiesce/close the file on the remote before pulling it","Verify both devices run the same core version so checksum scope matches","If it persists on a static file, log both hex digests and compare per-chunk checksums to localize the divergence"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"match remote_strategy.execute_pull(ctx, &src, &dst).await {\n    Ok(n) => Ok(n),\n    Err(e) if e.to_string() == \"Final checksum mismatch\" => {\n        // source likely changed mid-transfer; wait for quiescence and retry once\n        tokio::time::sleep(std::time::Duration::from_secs(5)).await;\n        remote_strategy.execute_pull(ctx, &src, &dst).await\n    }\n    Err(e) => Err(e),\n}","preventionTips":["Quiesce files on the remote before pulling them (close editors, stop writers)","Compare the logged expected/calculated digests to confirm a mid-transfer change vs a bug","Keep daemon versions aligned so checksum scope is identical on both sides"],"tags":["rust","spacedrive","pull","checksum","blake3","integrity","file-transfer"],"backgroundTag":null,"analyzedSha":"6dfeccf2113039e35f2ce735f945e70dc3e4ea45","analyzedAt":"2026-08-16T11:26:17.074Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}