jdx/mise · error
starting blob upload failed
Error message
starting blob upload failed: {} {}{} What it means
Thrown when the initial POST that starts a blob upload (or cross-repo mount) to an OCI registry returns a status other than 201 (mounted) or 202 (upload session started). The message includes the status code, the start URL, and an auth hint when credentials were involved.
Solutions
- Run `docker login <registry>` (or equivalent) to obtain valid push credentials.
- Create the repository/namespace in the registry if it requires pre-creation.
- Verify the registry URL and that your account has push permission.
- Retry if the registry was returning transient 5xx.
Example fix
// before: unauthenticated push
registry.push("ghcr.io/acme/app:latest")?;
// after: ensure login first
// $ docker login ghcr.io
registry.push("ghcr.io/acme/app:latest")?; Defensive patterns
Strategy: try-catch
Validate before calling
let ok = reqwest::Client::new()
.get(format!("https://{host}/v2/")).send().await
.map(|r| r.status().is_success() || r.status() == StatusCode::UNAUTHORIZED).unwrap_or(false); // 401 with WWW-Authenticate is normal
if !ok { eprintln!("registry unreachable/misconfigured: {host}"); } Try / catch
if let Err(e) = push_image(dir) {
let msg = e.to_string();
if msg.contains("401") || msg.contains("403") { relogin_and_retry(); }
else if msg.contains("404") { create_repo_or_fix_name(); }
else { return Err(e); }
} Prevention
- Run `docker login <registry>` before automated pushes; confirm token expiry windows.
- Verify the account has push scope for the target namespace.
- Create the repository beforehand on registries that don't auto-create.
When it happens
Trigger: `upload_blob_once` POSTing to the registry's `/v2/<name>/blobs/uploads/` endpoint and receiving e.g. 401/403 (bad credentials), 404 (repository doesn't exist), 405, or 5xx that is not retried away.
Common situations: Pushing to a repository that doesn't exist and the registry doesn't auto-create repos (404); expired or wrong push credentials (401/403); pushing to the wrong registry hostname; registry rate limits or outage.
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
AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17).
Data as JSON: /api/errors/764c4910f84543ce.
Report an issue: GitHub.
Appendix: source
Thrown at src/oci/registry.rs:1362
let mut rb = HTTP
.reqwest()?
.post(start_url.as_str())
.header("Content-Length", "0");
if let Some(a) = auth {
rb = rb.header("Authorization", a);
}
Ok(rb)
})
.await
.wrap_err_with(|| format!("POST {start_url}"))?;
let status = resp.status();
match status {
StatusCode::CREATED => return Ok(UploadOutcome::Mounted),
StatusCode::ACCEPTED => {}
s => {
// Let transient statuses bubble as retryable errors.
resp.error_for_status_ref()?;
bail!(
"starting blob upload failed: {} {}{}",
s.as_u16(),
start_url,
push_auth_hint(s, had_credential),
);
}
}
let mut location = self.resolve_location(&resp)?;
pr.set_position(0);
// 2. Transfer the bytes.
if size > UPLOAD_CHUNK_SIZE {
// Chunked: PATCH each segment, then a zero-length finalizing PUT.
let mut offset = 0u64;
while offset < size {
let len = UPLOAD_CHUNK_SIZE.min(size - offset);
let err_slot: UploadErrSlot = Default::default();
let resp = selfView on GitHub (pinned to 533346cc37)