jdx/mise · error

server returned inconsistent partial content

Error message

server returned inconsistent partial content

What it means

On resume, the server's 206 response is validated against the recorded partial-download state: the range must start at the saved offset, end at the saved total size, the content length must match, and any ETag/validator must match. If any check fails, mise restarts once without resume; if the retry is also inconsistent, it aborts with this error rather than appending bytes from a changed or different file.

Source

Thrown at src/http.rs:1043

                        }
                        restarted_without_resume = true;
                        continue;
                    };
                    let validator = response_validator(resp.headers());
                    let response_length_matches = resp
                        .content_length()
                        .is_none_or(|length| length == end - start + 1);
                    if start != offset
                        || end + 1 != total
                        || !response_length_matches
                        || state.total_size.is_some_and(|expected| expected != total)
                        || validator
                            .as_ref()
                            .is_some_and(|value| !value.matches(&state.validator))
                    {
                        partial.clear()?;
                        if restarted_without_resume {
                            bail!("server returned inconsistent partial content");
                        }
                        restarted_without_resume = true;
                        continue;
                    }
                    // Keep the filename associated with the bytes already on disk.
                    // A redirect target may change between requests even when the
                    // server accepts the validator and Range header. Replacing the
                    // stored hint could make the completed bytes use a different
                    // archive format than the response that started the partial.
                    let effective_filename = state.effective_filename;
                    let validator = validator.unwrap_or(state.validator);
                    (
                        offset,
                        Some(total),
                        Some(validator),
                        true,
                        effective_filename,
                    )

View on GitHub (pinned to afd2eddd3a)

Solutions

  1. Delete the partial download and its state file so mise fetches the file from scratch.
  2. Verify the URL still points at the same artifact; re-pin the tool version if the remote was updated.
  3. Retry later if the server is mid-rollout and serving inconsistent content across requests.

Example fix

// before: stale .part from an older release being resumed
# nothing to edit — stale partial state
// after: clear partial state and reinstall
rm -rf "$(mise cache_dir)/downloads"/<artifact>*.part*; mise install node@22
Defensive patterns

Strategy: fallback

Validate before calling

if let Some((etag, total)) = saved_state {
    let head = client.head(url).send().await?;
    if head.etag() != Some(&etag) || head.content_length() != Some(total) {
        delete_partial(); // remote changed; resume would be invalid
    }
}

Try / catch

if let Err(e) = download().await {
    if e.to_string().contains("inconsistent partial content") {
        delete_partial_download();
        download().await?; // restart clean
    } else { return Err(e); }
}

Prevention

When it happens

Trigger: Resuming a .part download where the remote file changed between sessions (new ETag/Last-Modified), the server returns a range not starting at the requested offset, the total size differs from the recorded one, or the Content-Length does not match end-start+1 — and a fresh restart hits the same mismatch.

Common situations: Resuming a download after the upstream released a new version at the same URL; a load-balanced pool serving different artifacts; an interrupted download left stale for days before retrying.

Understand the failure class

Background: Checksum mismatch errors: "checksum verification failed", "digest mismatch", "expected vs actual checksum" — what they mean and how to fix them — this error's family across 41 libraries.

Related errors


AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09). Data as JSON: /api/errors/de023c8acd737093. Report an issue: GitHub.