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

  1. Run `docker login <registry>` (or equivalent) to obtain valid push credentials.
  2. Create the repository/namespace in the registry if it requires pre-creation.
  3. Verify the registry URL and that your account has push permission.
  4. 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

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 = self

View on GitHub (pinned to 533346cc37)