tonhowtf/omniget · error · anyhow::Error

size mismatch: expected

Error message

size mismatch: expected {} bytes, got {}

What it means

After every segment reports done, the library compares the assembled .part file's size on disk (tokio::fs::metadata) against the expected total byte count derived from Content-Length. A mismatch means bytes were lost, duplicated, or never written despite all segments claiming success. It is the final integrity gate before renaming the part into place.

Solutions

  1. Delete the .part file and re-run the download; transient truncation often clears on retry.
  2. Verify each worker writes exactly (end - start + 1) bytes and seeks to the correct offset before writing.
  3. Validate the server's Content-Range in the 206 response matches the requested bytes range before writing (see the guard added around line 969).
  4. Check available disk space and that writes use write_all, not write, so partial writes are not silently accepted.

Example fix

// before
file.write(&buf).await?; // may write fewer bytes
// after
file.write_all(&buf).await?;
Defensive patterns

Strategy: validation

Validate before calling

// pre-check disk headroom and expected size before starting
let meta = std::fs::metadata(dest_dir)?;
let free = fs2::free_space(dest_dir)?;
if free <= expected_total { return Err("insufficient disk space"); }

Try / catch

match download(...).await {
    Err(e) if e.to_string().contains("size mismatch") => {
        // discard .part, re-download; if it repeats, suspect server/proxy truncation
    }
    other => { other?; }
}

Prevention

When it happens

Trigger: actual != total after join: a worker wrote fewer bytes than its range (truncated body/stream ended early), two workers wrote overlapping or gapped ranges, or the server sent a 206 whose Content-Range covered a different span than requested.

Common situations: Flaky proxies/middleboxes truncating responses, servers misreporting Content-Length, disk-full conditions that silently shorten writes, or off-by-one errors in exclusive/inclusive range end handling.

Understand the failure class

Background: Checksum mismatch errors: "checksum verification failed", "digest mismatch", "expected vs actual checksum" — what they mean and how to fix them — this error's family across 41 libraries.

Related errors


AI-assisted analysis of tonhowtf/omniget@8600b91f42 (2026-09-12). Data as JSON: /api/errors/f8ebe0b4b6ab8295. Report an issue: GitHub.

Appendix: source

Thrown at src-tauri/omniget-core/src/core/http_fetcher.rs:571

        if let Some(p) = resume_pump {
            p.abort();
        }
        let _ = progress_pump.await;

        if let Some(e) = first_err {
            return Err(e);
        }

        let segs = segments.lock().await;
        let all_done = segs
            .iter()
            .all(|s| s.state.load(Ordering::Relaxed) == SEG_DONE);
        if !all_done {
            return Err(anyhow!("not all segments completed"));
        }
        let actual = tokio::fs::metadata(part_path).await?.len();
        if actual != total {
            return Err(anyhow!(
                "size mismatch: expected {} bytes, got {}",
                total,
                actual
            ));
        }

        Ok(())
    }
}

struct ProbeResult {
    content_length: Option<u64>,
    accept_ranges: bool,
}

/// O que dá para saber de um recurso remoto antes de baixar.
#[derive(Debug, Clone)]
pub struct RemoteProbe {

View on GitHub (pinned to 8600b91f42)