Zackriya-Solutions/meetily · error

Download failed with status: {}

Error message

Download failed with status: {}

What it means

The download host answered with a non-success, non-206 status; the status code is embedded verbatim. Because only 206 counts as resume, a 416 Range Not Satisfiable from a stale or already-complete partial file also lands here. 404 means the file is gone, 403/429 mean access/rate limiting, 5xx are transient.

Source

Thrown at frontend/src-tauri/src/summary/summary_engine/model_manager.rs:512

            .await
            .map_err(|e| anyhow!("Failed to start download: {}", e))?;

        // Check response status - 200 OK (full download) or 206 Partial Content (resume)
        let (total_size, resuming) = if response.status() == reqwest::StatusCode::PARTIAL_CONTENT {
            // Server supports resume - total size = existing + remaining
            let remaining = response.content_length().unwrap_or(0);
            log::info!("Server supports resume, {} MB remaining", remaining / (1024 * 1024));
            (existing_size + remaining, true)
        } else if response.status().is_success() {
            // Server doesn't support resume or fresh download
            if existing_size > 0 {
                log::warn!("Server doesn't support resume, starting fresh download");
            }
            (response.content_length().unwrap_or(0), false)
        } else {
            let mut active = self.active_downloads.write().await;
            active.remove(model_name);
            return Err(anyhow!("Download failed with status: {}", response.status()));
        };

        log::info!("Total size: {} MB", total_size / (1024 * 1024));

        // Open file for append if resuming, or create new
        let file = if resuming {
            OpenOptions::new()
                .write(true)
                .append(true)
                .open(&file_path)
                .await
                .map_err(|e| anyhow!("Failed to open file for append: {}", e))?
        } else {
            fs::File::create(&file_path)
                .await
                .map_err(|e| anyhow!("Failed to create file: {}", e))?
        };

View on GitHub (pinned to 0281737d87)

Solutions

  1. On 416: delete the partial file and retry fresh — the existing file already satisfies or exceeds the range
  2. On 429/5xx: wait and retry; resume keeps the downloaded progress
  3. On 404/403: the model definition's download_url (or token) must be updated; the file moved at the host
  4. Surface the status code in the UI so users can distinguish 'try later' from 'broken link'

Example fix

// before: resuming blindly can trigger 416
request = request.header("Range", format!("bytes={}-", existing_size));

// after: validate the partial file against the remote size first
let head = client.head(&model_def.download_url).send().await?;
let remote_len = head.content_length().unwrap_or(0);
if existing_size >= remote_len && remote_len > 0 {
    tokio::fs::remove_file(&file_path).await?; // stale/complete partial: start fresh
    existing_size = 0;
}
Defensive patterns

Strategy: retry

Validate before calling

// Avoid 416: validate the partial file against the remote size before resuming
let head = client.head(&model_def.download_url).send().await?;
if let Some(remote) = head.content_length() {
    if existing_size >= remote {
        tokio::fs::remove_file(&file_path).await.ok(); // stale/complete partial
    }
}

Try / catch

match manager.download_model_detailed(name, cb).await {
    Err(e) if e.to_string().starts_with("Download failed with status: 416") => {
        delete_partial_file(name); manager.download_model_detailed(name, cb).await // fresh
    }
    Err(e) if e.to_string().starts_with("Download failed with status: 429") => {
        tokio::time::sleep(Duration::from_secs(60)).await; retry()
    }
    other => other,
}

Prevention

When it happens

Trigger: Model file removed or relocated at the CDN (404); auth token/hotlink expired (403); rate-limited after repeated downloads (429); resuming when the partial file already equals or exceeds the remote size (416); transient 502/503 from the origin.

Common situations: HuggingFace repo restructure removing a GGUF; too many downloads from one IP; leftover complete partial file after a crashed session making the Range header invalid.

Related errors


AI-assisted analysis of Zackriya-Solutions/meetily@0281737d87 (2026-08-16). Data as JSON: /api/errors/35c11d270b4e4382. Report an issue: GitHub.