rust-lang/cargo · error · anyhow::Error

multiple registries are configured with the same index url '

Error message

multiple registries are configured with the same index url '{}': {}

What it means

When Cargo needs to know the registry *name* for a given index URL (src/util/auth/mod.rs:231), it gathers candidate names from `CARGO_REGISTRIES_*_INDEX` env vars and from `[registries.*] index = ...` config, canonicalizes each URL, and matches against the requested index. If two or more configured registries canonicalize to the same index URL, it can't disambiguate the auth token/config and bails, listing the colliding names.

Source

Thrown at src/util/auth/mod.rs:266

        // Discover names from the configuration only if none were found in the environment.
        if names.len() == 0 {
            if let Some(registries) = gctx.values()?.get("registries") {
                let (registries, _) = registries.table("registries")?;
                for (name, value) in registries {
                    if let Some(v) = value.table(&format!("registries.{name}"))?.0.get("index") {
                        let (v, _) = v.string(&format!("registries.{name}.index"))?;
                        if index == &CanonicalUrl::new(&v.into_url()?)? {
                            names.push(name.clone());
                        }
                    }
                }
            }
        }
        names.sort();
        match names.len() {
            0 => None,
            1 => Some(std::mem::take(&mut names[0])),
            _ => anyhow::bail!(
                "multiple registries are configured with the same index url '{}': {}",
                &sid.as_url(),
                names.join(", ")
            ),
        }
    };

    // It's possible to have a registry configured in a Cargo config file,
    // then override it with configuration from environment variables.
    // If the name doesn't match, leave a note to help the user understand
    // the potentially confusing situation.
    if let Some(name) = name.as_deref() {
        if Some(name) != sid.alt_registry_key() {
            gctx.shell().note(format!(
                "name of alternative registry `{}` set to `{name}`",
                sid.url()
            ))?
        }

View on GitHub (pinned to 0e07a15537)

Solutions

  1. Inspect all `[registries.*]` blocks and `CARGO_REGISTRIES_*_INDEX` env vars; collapse duplicates so each canonical index URL maps to exactly one registry name.
  2. Decide on one protocol (sparse or git) per index and delete the other entry.
  3. If you need two registries that happen to share an index, give them genuinely different index URLs (e.g. different mirrors) or merge them.

Example fix

# before
[registries.crates-io-sparse]
index = "sparse+https://index.crates.io/"
[registries.crates-io-git]
index = "https://github.com/rust-lang/crates.io-index"   # both -> same canonical url after some setups

# after: keep one
[registries.crates-io-sparse]
index = "sparse+https://index.crates.io/"
Defensive patterns

Strategy: validation

Validate before calling

// Canonicalize all configured index URLs and assert uniqueness before building.
use url::Url;
fn unique_canonical_indexes(urls: &[String]) -> bool {
    let canon: Vec<_> = urls.iter().filter_map(|u| Url::parse(u).ok()).collect();
    let n = canon.len();
    canon.iter().map(|u| u.to_string()).collect::<std::collections::HashSet<_>>().len() == n
}

Prevention

When it happens

Trigger: Two `[registries.<name>]` entries (or env var + config) whose `index` URLs are equivalent after canonicalization (e.g. one with and one without trailing slash, `sparse+` prefix differences, or literally identical). Also when a registry is referenced by `--index`/Cargo.lock without a name and two configs match.

Common situations: Defining both a sparse and a git variant of the same registry under different names; copy-pasting a registry block and renaming it without changing the URL; an env var `CARGO_REGISTRIES_X_INDEX` duplicating a `[registries.y] index` that points to the same place; migrating from git to sparse index and forgetting to remove the old entry.

Related errors


AI-assisted analysis of rust-lang/cargo@0e07a15537 (2026-08-06). Data as JSON: /data/errors/1b07d3387be6d838.json. Report an issue: GitHub.