jdx/mise · error
server returned partial content without a resumable request
Error message
server returned partial content without a resumable request
What it means
During a resumable HTTP download, a server responded 206 (partial content) even though the request was not resumable (no resume state was available, and a previous restart without resume already happened). mise cannot trust partial data it never asked for, so it clears the partial and bails.
Solutions
- Bypass or fix the proxy/cache in front of the server — it's returning partial content for non-Range requests.
- Retry from a different mirror or direct download source.
- Clear the partial download cache and retry in case stale state contributed.
Defensive patterns
Strategy: fallback
Validate before calling
curl -fsSI -H 'Range: bytes=0-0' "$url" | grep -i '^content-range:' || echo "server mishandles Range requests"
Prevention
- Probe servers/proxies for correct Range behavior before relying on resumable downloads
- Bypass caching layers that always answer 206
- Use mirrors known to support conditional GET correctly
When it happens
Trigger: The downloader retries a failed download without a Range header (after clearing resume state), the server still returns 206 Partial Content, and this is the second time it happens (restarted_without_resume already true).
Common situations: Broken/misbehaving proxy or CDN that always returns 206 regardless of Range headers; buggy caching layer mangling requests; server-side middleware that rewrites Range requests.
Related errors
- server returned an invalid Content-Range response
- server returned inconsistent partial content
- download cancelled by user
- HTTP download timed out after
- should not be called for system tool
AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17).
Data as JSON: /api/errors/4b1be733b03966ff.
Report an issue: GitHub.
Appendix: source
Thrown at src/http.rs:1140
debug!("range request at offset {offset} was unsatisfied for {total} bytes");
}
partial.clear()?;
if offset > 0 && !restarted_without_resume {
restarted_without_resume = true;
continue;
}
resp.error_for_status_ref()?;
}
let (write_offset, total_size, validator, resumable, effective_filename) =
if resp.status() == StatusCode::PARTIAL_CONTENT {
let Some((state, _)) = resume else {
partial.clear()?;
if !restarted_without_resume {
restarted_without_resume = true;
continue;
}
bail!("server returned partial content without a resumable request");
};
let content_range = resp
.headers()
.get(CONTENT_RANGE)
.and_then(|value| value.to_str().ok())
.and_then(parse_content_range);
let Some(ParsedContentRange::Bytes { start, end, total }) = content_range
else {
partial.clear()?;
if restarted_without_resume {
bail!("server returned an invalid Content-Range response");
}
restarted_without_resume = true;
continue;
};
let validator = response_validator(resp.headers());
let response_length_matches = resp
.content_length()View on GitHub (pinned to 533346cc37)