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
- Inspect all `[registries.*]` blocks and `CARGO_REGISTRIES_*_INDEX` env vars; collapse duplicates so each canonical index URL maps to exactly one registry name.
- Decide on one protocol (sparse or git) per index and delete the other entry.
- 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
- Maintain exactly one registry name per canonical index URL across config + env.
- When migrating git->sparse, remove the old `[registries.<name>]` entry.
- Use distinct mirror URLs if you genuinely need two registries.
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
- path `{}` is not a blob in the git repo
- config.json not found
- sparse registry url must end in a slash `/`: {url}
- cache expected 4 bytes for index schema version
- registry said cache valid when no cache exists
AI-assisted analysis of rust-lang/cargo@0e07a15537 (2026-08-06).
Data as JSON: /data/errors/1b07d3387be6d838.json.
Report an issue: GitHub.