{"record":{"id":"8add3d4fcbb516c9","repo":"spacedriveapp/spacedrive","slug":"chunk-checksum-mismatch","errorCode":null,"errorMessage":"Chunk {} checksum mismatch","messagePattern":"Chunk (.+?) checksum mismatch","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"critical","filePath":"core/src/ops/files/copy/strategy.rs","lineNumber":656,"sourceCode":"\t\t\tlet msg_len = u32::from_be_bytes(len_buf) as usize;\n\n\t\t\tlet mut msg_buf = vec![0u8; msg_len];\n\t\t\trecv_stream.read_exact(&mut msg_buf).await?;\n\n\t\t\tlet msg: crate::service::network::protocol::file_transfer::FileTransferMessage =\n\t\t\t\trmp_serde::from_slice(&msg_buf)?;\n\n\t\t\tmatch msg {\n\t\t\t\tcrate::service::network::protocol::file_transfer::FileTransferMessage::FileChunk {\n\t\t\t\t\tchunk_index,\n\t\t\t\t\tdata,\n\t\t\t\t\tchunk_checksum,\n\t\t\t\t\t..\n\t\t\t\t} => {\n\t\t\t\t\t// Verify chunk checksum\n\t\t\t\t\tlet calculated = blake3::hash(&data);\n\t\t\t\t\tif calculated.as_bytes() != &chunk_checksum {\n\t\t\t\t\t\treturn Err(anyhow::anyhow!(\n\t\t\t\t\t\t\t\"Chunk {} checksum mismatch\",\n\t\t\t\t\t\t\tchunk_index\n\t\t\t\t\t\t));\n\t\t\t\t\t}\n\n\t\t\t\t\t// Write chunk\n\t\t\t\t\tfile.write_all(&data).await?;\n\t\t\t\t\tif let Some(h) = &mut hasher {\n\t\t\t\t\t\th.update(&data);\n\t\t\t\t\t}\n\t\t\t\t\ttotal_bytes_received += data.len() as u64;\n\n\t\t\t\t\t// Progress callback\n\t\t\t\t\tif let Some(cb) = progress_callback {\n\t\t\t\t\t\tcb(total_bytes_received, file_size);\n\t\t\t\t\t}\n\n\t\t\t\t\tif chunk_index % 100 == 0 {","sourceCodeStart":638,"sourceCodeEnd":674,"githubUrl":"https://github.com/spacedriveapp/spacedrive/blob/6dfeccf2113039e35f2ce735f945e70dc3e4ea45/core/src/ops/files/copy/strategy.rs#L638-L674","documentation":"Each FileChunk carries a per-chunk blake3 checksum; recomputing blake3 over the received bytes mismatched (strategy.rs:653-660), so chunk data was corrupted, duplicated, or reordered in flight or in memory. With QUIC's integrity protection, genuine wire corruption is unlikely — suspect a producer bug, memory issue, or build mismatch. Unlike the byte-count and final-checksum failures, this branch returns WITHOUT deleting the partial destination file, so a corrupt partial file remains on disk.","triggerScenarios":"Sender/receiver running mismatched versions that frame chunks differently; buffer corruption under memory pressure; duplicated chunk delivery after a stream event; producer-side serialization bug on the remote.","commonSituations":"Mixed daemon versions during rolling upgrades; hardware memory errors; reproducible failure at the same chunk index indicating a protocol bug.","solutions":["Delete any leftover partial file at the destination, then retry the transfer","Verify both devices run identical core versions so chunk framing matches","If it reproduces at the same chunk index, capture sender-side logs and report a protocol bug","If corruption recurs across unrelated transfers, run a memory diagnostic on both machines"],"exampleFix":"// before (strategy.rs, current behavior leaves the partial file)\nif calculated.as_bytes() != &chunk_checksum {\n    return Err(anyhow::anyhow!(\"Chunk {} checksum mismatch\", chunk_index));\n}\n\n// after: clean up the corrupt partial file like the other integrity failures\nif calculated.as_bytes() != &chunk_checksum {\n    let _ = fs::remove_file(&final_dest_path).await;\n    return Err(anyhow::anyhow!(\"Chunk {} checksum mismatch\", chunk_index));\n}","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().starts_with(\"Chunk\") && e.to_string().ends_with(\"checksum mismatch\") => {\n        // NOTE: strategy does NOT delete the partial file here — remove it before retrying\n        let _ = tokio::fs::remove_file(&expected_dest).await;\n        remote_strategy.execute_pull(ctx, &src, &dst).await\n    }\n    Err(e) => Err(e),\n}","preventionTips":["Delete the partial destination file before retrying — this branch leaves it behind","Pin both devices to the same core version so chunk framing matches","Escalate to a bug report if the same chunk index fails repeatedly"],"tags":["rust","spacedrive","pull","checksum","data-corruption","blake3","file-transfer"],"backgroundTag":null,"analyzedSha":"6dfeccf2113039e35f2ce735f945e70dc3e4ea45","analyzedAt":"2026-08-16T11:26:17.074Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}