jdx/mise · error · eyre::Report

fetching {url} failed: {}{hint} {}

Error message

fetching {url} failed: {}{hint}
{}

What it means

fetch_manifest_json is the generic manifest/index GET used while resolving and pulling base images from an OCI registry. Any non-2xx response that is not a retried transient failure (5xx/408/429 are retried with backoff upstream) lands here: mise prints the HTTP status, an auth hint for 401/403 (credentials rejected vs. `docker login` needed), and the registry's response body.

Source

Thrown at src/oci/registry.rs:465

                rb = rb.header("Authorization", a);
            }
            Ok(rb)
        })
        .await
        .wrap_err_with(|| format!("fetching {url}"))?;
    let status = resp.status();
    if !status.is_success() {
        let hint = if status == StatusCode::UNAUTHORIZED || status == StatusCode::FORBIDDEN {
            if session.has_credential() {
                " — the stored credentials were rejected or lack access to this image"
            } else {
                " — the image may be private; run `docker login` (or `podman login`) for this registry"
            }
        } else {
            ""
        };
        let body = resp.text().await.unwrap_or_default();
        bail!(
            "fetching {url} failed: {}{hint}\n{}",
            status.as_u16(),
            body.trim()
        );
    }
    let content_type = header_str(&resp, "content-type");
    let body: serde_json::Value = resp
        .json()
        .await
        .wrap_err_with(|| format!("parsing JSON response from {url}"))?;
    Ok((body, content_type))
}

/// Retry a transient-failure-prone operation with mise's standard backoff
/// schedule. Transient means connect/timeout/body errors and 5xx/408/429
/// statuses surfaced via `error_for_status`. A macro rather than a generic
/// fn so the operation expression can reborrow `&mut` state (the
/// [`AuthSession`]) on every attempt.

View on GitHub (pinned to 9dcfcaa0dc)

Solutions

  1. For 401/403: run `docker login` (or `podman login`) against the registry named in the URL — for ghcr.io use a PAT with `read:packages`
  2. For 404: verify the exact repository and tag/digest with `crane manifest <ref>` or `docker pull <ref>`; fix the base image reference in mise.toml
  3. Read the body line — registries return structured codes (NAME_UNKNOWN, DENIED, TOOMANYREQUESTS) that pinpoint the cause
  4. For transient-looking failures, re-run the build: mise already retried 5xx/408/429, but registry-side state may recover

Example fix

# before — private base image, no credentials on CI
base_image = "ghcr.io/acme/private-base:1"

# after — log in first, then build
docker login ghcr.io -u $USER -p $GITHUB_TOKEN
mise oci build
Defensive patterns

Strategy: try-catch

Validate before calling

# Verify the base image is pullable with current credentials before building:
crane manifest ghcr.io/acme/private-base:1 >/dev/null && echo "ref+auth ok"
# Or with docker: docker pull ghcr.io/acme/private-base:1 >/dev/null && echo ok

Try / catch

// When invoking mise programmatically, branch on the embedded status code:
let msg = String::from_utf8_lossy(&out.stderr);
if msg.contains("fetching") && msg.contains("failed: 401") {
    // run `docker login <registry>` then retry the build once
} else if msg.contains("failed: 404") {
    // base image ref or tag is wrong — fix config, do not retry
} else {
    // 5xx etc. — retry with backoff (mise already retried transient statuses)
}

Prevention

When it happens

Trigger: Pulling a base image that does not exist (404 — typo'd repo/tag, deleted tag), a private image without credentials (401/403 with the docker login hint), stored credentials rejected, or 4xx rejections from proxies and misconfigured self-hosted registries.

Common situations: ghcr.io private images on CI without prior `docker login`; upstream tags renamed or removed; rate-limit responses after retries exhausted; corporate proxies returning 403 for registry hosts.

Related errors


AI-assisted analysis of jdx/mise@9dcfcaa0dc (2026-08-17). Data as JSON: /api/errors/4860404b6875327e. Report an issue: GitHub.