{"id":"1b07d3387be6d838","repo":"rust-lang/cargo","slug":"multiple-registries-are-configured-with-the-same-i","errorCode":null,"errorMessage":"multiple registries are configured with the same index url '{}': {}","messagePattern":"multiple registries are configured with the same index url '(.+?)': (.+?)","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src/util/auth/mod.rs","lineNumber":266,"sourceCode":"        // Discover names from the configuration only if none were found in the environment.\n        if names.len() == 0 {\n            if let Some(registries) = gctx.values()?.get(\"registries\") {\n                let (registries, _) = registries.table(\"registries\")?;\n                for (name, value) in registries {\n                    if let Some(v) = value.table(&format!(\"registries.{name}\"))?.0.get(\"index\") {\n                        let (v, _) = v.string(&format!(\"registries.{name}.index\"))?;\n                        if index == &CanonicalUrl::new(&v.into_url()?)? {\n                            names.push(name.clone());\n                        }\n                    }\n                }\n            }\n        }\n        names.sort();\n        match names.len() {\n            0 => None,\n            1 => Some(std::mem::take(&mut names[0])),\n            _ => anyhow::bail!(\n                \"multiple registries are configured with the same index url '{}': {}\",\n                &sid.as_url(),\n                names.join(\", \")\n            ),\n        }\n    };\n\n    // It's possible to have a registry configured in a Cargo config file,\n    // then override it with configuration from environment variables.\n    // If the name doesn't match, leave a note to help the user understand\n    // the potentially confusing situation.\n    if let Some(name) = name.as_deref() {\n        if Some(name) != sid.alt_registry_key() {\n            gctx.shell().note(format!(\n                \"name of alternative registry `{}` set to `{name}`\",\n                sid.url()\n            ))?\n        }","sourceCodeStart":248,"sourceCodeEnd":284,"githubUrl":"https://github.com/rust-lang/cargo/blob/0e07a155371a6ce88ae53a2c00df940280c09a67/src/util/auth/mod.rs#L248-L284","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"# before\n[registries.crates-io-sparse]\nindex = \"sparse+https://index.crates.io/\"\n[registries.crates-io-git]\nindex = \"https://github.com/rust-lang/crates.io-index\"   # both -> same canonical url after some setups\n\n# after: keep one\n[registries.crates-io-sparse]\nindex = \"sparse+https://index.crates.io/\"","handlingStrategy":"validation","validationCode":"// Canonicalize all configured index URLs and assert uniqueness before building.\nuse url::Url;\nfn unique_canonical_indexes(urls: &[String]) -> bool {\n    let canon: Vec<_> = urls.iter().filter_map(|u| Url::parse(u).ok()).collect();\n    let n = canon.len();\n    canon.iter().map(|u| u.to_string()).collect::<std::collections::HashSet<_>>().len() == n\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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."],"tags":["cargo","registry","auth","config","validation"],"analyzedSha":"0e07a155371a6ce88ae53a2c00df940280c09a67","analyzedAt":"2026-08-06T01:46:58.334Z","schemaVersion":2}