cjpais/Handy · error · anyhow::Error

server sent more than the expected {} bytes

Error message

server sent more than the expected {} bytes

What it means

Body-size cap enforcement: the server streamed past known_total (catalog-pinned size or advertised Content-Length). A server that overshoots its own contract is provably misbehaving, so the writer cuts the transfer at the first overflowing chunk, drops the file handle, and deletes everything written so far — preventing both disk-fill by an untrusted host and tainted data.

Source

Thrown at src-tauri/src/managers/model/download.rs:347

                        DOWNLOAD_STALL_TIMEOUT.as_secs()
                    )),
                    Ok(None) => break,
                    Ok(Some(chunk)) => chunk?,
                },
                _ = cancel_token.cancelled() => {
                    // Keep the partial for resume; caller handles state cleanup.
                    return Ok(HttpDownloadOutcome::Cancelled);
                }
            };
            // An untrusted server must not be able to fill the disk: cut the
            // transfer at the first byte past the known total instead of
            // trusting it to eventually close the stream. Everything written
            // so far is tainted by a provably-misbehaving server — clear it.
            if let Some(cap) = known_total {
                if downloaded + chunk.len() as u64 > cap {
                    drop(file);
                    let _ = fs::remove_file(partial_path);
                    return Err(anyhow::anyhow!(
                        "server sent more than the expected {} bytes",
                        cap
                    ));
                }
            }
            file.write_all(&chunk)?;
            downloaded += chunk.len() as u64;
            if last_emit.elapsed() >= throttle {
                emit_progress(downloaded);
                last_emit = Instant::now();
            }
        }
        file.flush()?;
        drop(file);
        emit_progress(downloaded);

        if let Some(expected) = known_total {
            let actual = partial_path.metadata()?.len();

View on GitHub (pinned to 98a4d80cce)

Solutions

  1. Refresh the catalog/app so expected_size matches the real object, then retry
  2. Verify the real size: curl -sI <url> and compare Content-Length against the catalog
  3. Switch to the official HuggingFace revision whose size is pinned
  4. Report or stop using a mirror that consistently overshoots
Defensive patterns

Strategy: retry

Try / catch

match downloader.download_http_resumable(...).await {
    Ok(outcome) => Ok(outcome),
    Err(e) if e.to_string().starts_with("server sent more than") => {
        // server overshoots the pinned size: metadata is stale or the host is bad
        refresh_catalog_or_switch_source(model_id).await?;
        downloader.download_http_resumable(...).await
    }
    Err(e) => Err(e),
}

Prevention

When it happens

Trigger: Server sends an object larger than the pinned expected_size (upstream re-published a bigger file, stale catalog); server advertises a small Content-Length then streams more; a concatenating proxy.

Common situations: Catalog size skew after upstream updates; misconfigured mirrors serving bundles instead of single files.

Related errors


AI-assisted analysis of cjpais/Handy@98a4d80cce (2026-08-16). Data as JSON: /api/errors/1e4eb633b0ac40d7. Report an issue: GitHub.