spacedriveapp/spacedrive · error · anyhow::Error

Byte count mismatch: expected {}, got {}

Error message

Byte count mismatch: expected {}, got {}

What it means

The peer's TransferComplete message declared total_bytes, but the sum of received chunk lengths differs (strategy.rs:686-694) — chunks were lost, duplicated, or the accounting desynchronized. The partial destination file is removed and the transfer fails as a unit; nothing partial is kept.

Source

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

						cb(total_bytes_received, file_size);
					}

					if chunk_index % 100 == 0 {
						ctx.log(format!(
							"PULL progress: chunk {}, {} / {} bytes",
							chunk_index, total_bytes_received, file_size
						));
					}
				}
				crate::service::network::protocol::file_transfer::FileTransferMessage::TransferComplete {
					final_checksum,
					total_bytes,
					..
				} => {
					// Verify byte count first
					if total_bytes != total_bytes_received {
						let _ = fs::remove_file(&final_dest_path).await;
						return Err(anyhow::anyhow!(
							"Byte count mismatch: expected {}, got {}",
							total_bytes,
							total_bytes_received
						));
					}

					// Verify final checksum if enabled
					if verify_checksum {
						if let Some(h) = hasher.take() {
							let calculated = h.finalize();
							let calculated_hex = calculated.to_hex().to_string();

							if final_checksum.is_empty() {
								// Warn when checksum verification enabled but no checksum provided
								ctx.log("Warning: checksum verification enabled but remote did not provide checksum".to_string());
							} else if calculated_hex != final_checksum {
								error!(
									"Final checksum mismatch: expected {}, got {}",

View on GitHub (pinned to 6dfeccf211)

Solutions

  1. Retry the full pull — the mismatch is fatal to this attempt and cleanup already ran
  2. Confirm identical versions on both devices so byte accounting matches
  3. If it recurs, log received chunk indices vs expected to find where the count diverges
  4. Check whether an EOF-like stream error (containing 'finish'/'closed') interleaved before completion
Defensive patterns

Strategy: retry

Try / catch

match remote_strategy.execute_pull(ctx, &src, &dst).await {
    Ok(n) => Ok(n),
    Err(e) if e.to_string().starts_with("Byte count mismatch") => {
        // partial file already removed; a fresh retry re-establishes clean accounting
        remote_strategy.execute_pull(ctx, &src, &dst).await
    }
    Err(e) => Err(e),
}

Prevention

When it happens

Trigger: A chunk message skipped or double-processed after a stream hiccup; sender and receiver computing byte totals differently (version mismatch); loop exiting early on a misdetected EOF ('finish'/'closed') before a late TransferComplete arrives.

Common situations: Mixed daemon versions during upgrade; flaky connections producing partial reads; large multi-chunk transfers where one stream event desyncs the count.

Related errors


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