jdx/mise · error
blob upload failed
Error message
blob upload failed: {}{}
{} What it means
upload_blob_once finalized an OCI registry blob upload with a PUT and got a non-success HTTP status; the message embeds the status and the registry's error body. The named OCI registry rejected the upload (auth, digest mismatch, or quota are common).
Solutions
- Verify the local blob's digest (`sha256sum <file>`) matches the descriptor in the manifest; re-download/rebuild the blob if not.
- Re-authenticate and retry the push.
- Retry after transient 5xx; the upload restarts with a fresh session.
- Check available disk space / registry quota — some registries reject on quota with 413.
Defensive patterns
Strategy: validation
Validate before calling
let digest =Sha256::digest(&bytes);
let expected = &manifest.layers[i].digest; // "sha256:..."
assert_eq!(format!("sha256:{digest:x}"), *expected, "local blob corrupt; re-pull before push"); Try / catch
if let Err(e) = push_image(dir) {
let msg = e.to_string();
if msg.contains("400") { verify_blob_digests(dir); }
if msg.contains("401") || msg.contains("403") { relogin_and_retry(); }
} Prevention
- Verify local blob digests against manifest descriptors before pushing.
- Re-authenticate before long uploads; refresh tokens proactively.
- Check registry storage quota if blobs are large.
When it happens
Trigger: `upload_blob_once` sending the final PUT (with digest query parameter) to close the upload session and receiving e.g. 400 (digest mismatch), 401 (expired token), or 5xx.
Common situations: The assembled blob doesn't match the digest in the PUT's `digest` param (corrupted file on disk or interrupted download into the staging path); credentials expiring during a long upload; registry errors under load.
Understand the failure class
Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.
Related errors
- blob chunk upload failed
- starting blob upload failed
- fetching blob failed
- fetching failed
- fetching failed
AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17).
Data as JSON: /api/errors/5ac13828f2bb0fd0.
Report an issue: GitHub.
Appendix: source
Thrown at src/oci/registry.rs:1436
let resp = self
.session
.send(|auth| {
let mut rb = HTTP
.reqwest()?
.put(put_url.as_str())
.header("Content-Length", "0");
if let Some(a) = auth {
rb = rb.header("Authorization", a);
}
Ok(rb)
})
.await
.wrap_err("PUT blob upload (finalize)")?;
let status = resp.status();
if !status.is_success() {
resp.error_for_status_ref()?;
let body = resp.text().await.unwrap_or_default();
bail!(
"blob upload failed: {}{}\n{}",
status.as_u16(),
push_auth_hint(status, had_credential),
body.trim(),
);
}
} else {
// Monolithic PUT with ?digest=…
let mut put_url = location;
put_url.query_pairs_mut().append_pair("digest", digest);
let err_slot: UploadErrSlot = Default::default();
let resp = self
.session
.send(|auth| {
Ok(build_upload_request(
HTTP.reqwest()?.put(put_url.as_str()),
auth,
path,View on GitHub (pinned to 533346cc37)