jdx/mise · error

fetching current index for

Error message

fetching current index for {url} failed: {}

What it means

existing_index_entries fetches the current tag index (manifest) for a URL; any status other than 200 (index found) or 404 (treated as empty index) raises this error. The status code is included so the developer can tell whether it is auth, permission, or a server problem.

Solutions

  1. Check the status code in the message: 401/403 → fix credentials/permissions; 5xx → retry later
  2. Ensure a valid read token is configured for private repositories
  3. Retry after backoff if the registry returned 429 or 5xx
  4. Verify the registry URL and repository name are correct

Example fix

// before
// fetching current index for https://ghcr.io/v2/org/img/manifests/index failed: 401
// after
// supply credentials for ghcr.io before running the tag-index update
Defensive patterns

Strategy: retry

Validate before calling

// curl -I the manifest URL with the same token to confirm 200/404 before calling the API

Try / catch

try { entries = await existingIndexEntries(url) } catch (e) { if (/failed: (5\d\d|429)/.test(e.message)) await backoffRetry(); else throw e; }

Prevention

When it happens

Trigger: update_tag_index calls existing_index_entries and the GET of the manifest returns e.g. 401 (bad credentials), 403 (read denied), 5xx (registry outage), or 429 (rate limit) — anything not 200/404.

Common situations: Private repository fetched without a token, anonymous requests rate-limited by Docker Hub/GHCR, transient registry 5xx during an update, proxy intercepting the request.

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/45065e6950c85f10. Report an issue: GitHub.

Appendix: source

Thrown at src/oci/registry.rs:1580

            MEDIA_TYPE_OCI_MANIFEST,
            MEDIA_TYPE_DOCKER_MANIFEST,
        ]
        .join(", ");
        let resp = self
            .session
            .send(|auth| {
                let mut rb = HTTP.reqwest()?.get(&url).header("Accept", &accept);
                if let Some(a) = auth {
                    rb = rb.header("Authorization", a);
                }
                Ok(rb)
            })
            .await
            .wrap_err_with(|| format!("GET {url}"))?;
        match resp.status() {
            StatusCode::OK => {}
            StatusCode::NOT_FOUND => return Ok(vec![]),
            s => bail!("fetching current index for {url} failed: {}", s.as_u16()),
        }
        let content_type = header_str(&resp, "content-type");
        let bytes = resp.bytes().await?;
        let body: serde_json::Value = serde_json::from_slice(&bytes)?;

        // Already an index — take its entries.
        if body.get("manifests").map(|m| m.is_array()).unwrap_or(false) {
            let index: ImageIndex =
                serde_json::from_slice(&bytes).wrap_err("parsing existing image index")?;
            return Ok(index.manifests);
        }

        // A single-platform manifest: wrap it as an index entry so its
        // platform survives the upgrade to an index.
        match self
            .wrap_single_manifest(&bytes, &body, &content_type)
            .await
        {

View on GitHub (pinned to 533346cc37)