tonhowtf/omniget · error · anyhow::Error
incomplete segment: of bytes
Error message
incomplete segment: {} of {} bytes What it means
After the stream ends (or the ceiling is reached), download_segment verifies the number of bytes currently downloaded for the segment equals its current target. If fewer bytes were written than required, the segment is declared incomplete so the worker retries it instead of assembling a corrupt file.
Solutions
- Retry the segment — a fresh ranged GET resumes at the written offset
- Compare Content-Length/Content-Range with the requested range to detect server-side truncation
- Check disk space and file-descriptor limits if truncation is local (though this path is server-side)
- If a specific server always truncates, exclude it or use single-stream download
Defensive patterns
Strategy: retry
Validate before calling
// compare advertised size with requested range before trusting a segment
let head = client.head(url).send().await?;
let len: u64 = head.headers().get("content-length")
.and_then(|v| v.to_str().ok()).and_then(|s| s.parse().ok()).unwrap_or(0);
if len == 0 { eprintln!("unknown size; segmented integrity check unreliable"); } Try / catch
if let Err(e) = download_segment(&seg, &cancel).await {
if e.to_string().contains("incomplete segment") {
tracing::warn!("segment truncated by server; retrying from offset");
download_segment(&seg, &cancel).await?;
} else { return Err(e.into()); }
} Prevention
- Cap segment retries and mark host unreliable after repeated truncation
- Verify final file hash when the source publishes one
- Log stop_reason and Content-Range for every segment to diagnose truncation
- Prefer hosts with Accept-Ranges + correct Content-Length
When it happens
Trigger: Stream ended (eof or 'ceiling shrank') with written bytes < (end_ceiling+1 - range_start); e.g. server closed the connection early after a partial body, or the stop_reason logic exited before reaching target.
Common situations: Origin truncating large files; Content-Length shorter than Range requested; connection drop that reqwest surfaces as clean EOF; misconfigured server clamping ranges.
Related errors
- HTTP
- server answered range at byte
- server did not honor Range (HTTP 200)
- Size mismatch: expected
- a API do TikTok respondeu HTTP
AI-assisted analysis of tonhowtf/omniget@8600b91f42 (2026-09-12).
Data as JSON: /api/errors/f7778e6e5c0a610f.
Report an issue: GitHub.
Appendix: source
Thrown at src-tauri/omniget-core/src/core/http_fetcher.rs:1081
written
);
return Err(anyhow!("read timed out after {:?}", cfg.read_timeout));
}
}
}
file.flush().await?;
let cur_end = seg.end_ceiling.load(Ordering::Relaxed);
let cur_target = (cur_end - begin) + 1;
let cur_dl = seg.downloaded.load(Ordering::Relaxed);
tracing::debug!(
"[http_fetcher] segment {}: {} bytes in {:.2}s ({})",
seg.id,
written,
started.elapsed().as_secs_f64(),
stop_reason
);
if cur_dl < cur_target {
return Err(anyhow!(
"incomplete segment: {} of {} bytes",
cur_dl,
cur_target
));
}
Ok(())
}
fn is_fatal(err: &anyhow::Error) -> bool {
let m = err.to_string();
for code in &[
"HTTP 400", "HTTP 401", "HTTP 403", "HTTP 404", "HTTP 405", "HTTP 410", "HTTP 451",
] {
if m.contains(code) {
return true;
}
}
if m.contains("HTML instead of media") {View on GitHub (pinned to 8600b91f42)