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
- 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`
- 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
- Read the body line — registries return structured codes (NAME_UNKNOWN, DENIED, TOOMANYREQUESTS) that pinpoint the cause
- 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
- Run `docker login` for every private registry as the first CI step
- Pin base images by digest so renamed/deleted tags cannot break builds
- Add a preflight `crane manifest <base-ref>` check in CI to fail fast with a clearer signal
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
- fetching blob {url} failed: {}
- fetching {manifest_url} failed: {}
- starting blob upload failed: {} {}{}
- blob chunk upload failed: {}{} {}
- blob upload failed: {}{} {}
AI-assisted analysis of jdx/mise@9dcfcaa0dc (2026-08-17).
Data as JSON: /api/errors/4860404b6875327e.
Report an issue: GitHub.