tonhowtf/omniget · error · anyhow::Error

HTTP

Error message

HTTP {}

What it means

download_segment only accepts HTTP 206 Partial Content when fetching a byte range. If the server replies 200 (ignoring the Range header) or any non-206 status, it refuses to write the body, because writing a full body at a segment offset would silently corrupt the assembled file.

Solutions

  1. Verify the server/CDN supports Range requests (curl -H 'Range: bytes=0-99' -I and expect 206 with Accept-Ranges: bytes)
  2. Check the URL is still valid and authorized (403/404 usually means expired token or deleted object)
  3. Remove or reconfigure proxies/middlewares that strip the Range header
  4. Fall back to a single-stream (non-segmented) download for this host

Example fix

// server ignores Range: bytes=100-199 -> 200 with full body
// fix: confirm range support before segmenting
curl -sI -H "Range: bytes=0-99" https://example.com/file.bin  # expect HTTP/1.1 206 Partial Content
Defensive patterns

Strategy: retry

Validate before calling

// probe range support before segmented download
let resp = client.head(url).send().await?;
let range_ok = resp.headers().get("accept-ranges").map(|v| v == "bytes").unwrap_or(false);
if !range_ok { use_single_stream_download(); }

Type guard

fn is_partial_content(status: reqwest::StatusCode) -> bool { status == reqwest::StatusCode::PARTIAL_CONTENT }

Try / catch

match download_segment(...).await {
    Err(e) if e.to_string().contains("HTTP 200") || e.to_string().starts_with("HTTP ") => {
        log::warn!("range not honored, falling back to single stream");
        single_stream_download().await?;
    }
    Err(e) => return Err(e),
    Ok(()) => {}
}

Prevention

When it happens

Trigger: A worker segment request gets HTTP 200 because the server ignored the Range header, or gets 403/404/416/5xx for the ranged GET issued by download_segment.

Common situations: Servers/proxies without range support (some CDNs, CGI scripts, PHP handlers) answering 200; wrong or expired presigned URL returning 403; file removed returning 404; rate-limited or overloaded origin returning 5xx.

Related errors


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

Appendix: source

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

    let mut req = client.get(url);
    if let Some(h) = headers {
        req = req.headers(headers_without_range(h));
    }
    req = req.header(
        reqwest::header::RANGE,
        format!("bytes={}-{}", range_start, end),
    );

    let resp = tokio::time::timeout(cfg.connect_timeout, req.send())
        .await
        .map_err(|_| anyhow!("connect timeout"))??;

    let status = resp.status();
    if status != reqwest::StatusCode::PARTIAL_CONTENT {
        if status.is_success() {
            return Err(anyhow!("server did not honor Range (HTTP 200)"));
        }
        return Err(anyhow!("HTTP {}", status));
    }

    // A 206 alone is not proof the server gave us the slice we asked for. If it
    // answers a different offset and we write the body at ours anyway, the file
    // still ends up the right size and is silently corrupt — the one failure
    // mode a segmented download cannot detect later.
    if let Some(start) = content_range_start(resp.headers()) {
        if start != range_start {
            return Err(anyhow!(
                "server answered range at byte {} but {} was requested",
                start,
                range_start
            ));
        }
    }

    if let Some(ct) = resp.headers().get(reqwest::header::CONTENT_TYPE) {
        if let Ok(s) = ct.to_str() {

View on GitHub (pinned to 8600b91f42)