{"record":{"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":null,"httpStatus":null,"severity":"error","filePath":"src/util/auth/mod.rs","lineNumber":193,"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":175,"sourceCodeEnd":211,"githubUrl":"https://github.com/rust-lang/cargo/blob/98a09e7e7d62850f14e5b6132101fc1edd19a16f/src/util/auth/mod.rs#L175-L211","documentation":"Cargo resolves a registry `SourceId` back to a configured registry name (for credential lookup). It collects candidate names from env vars (`CARGO_REGISTRIES_<NAME>_INDEX`) and then from `[registries.*]` config. If two or more configured registries share the same canonical index URL, the mapping is ambiguous and Cargo bails, listing the colliding names.","triggerScenarios":"In `auth::registry_name_from_sid`, after gathering names whose index URL canonicalizes to the same value as the source's, `names.len() > 1`. Triggered by defining two `[registries.<name>]` entries (or env + config) with identical (or canonical-equivalent) `index` URLs.","commonSituations":"User aliases the same registry under two names (e.g. a corporate mirror and the original); leftover config from a rename where both old and new point at the same index; env var (`CARGO_REGISTRIES_X_INDEX`) duplicating a config-level entry pointing at the same URL.","solutions":["Remove the duplicate registry definition so only one name maps to each index URL.","If you need an alias, use `[source.<alias>] registry = \"<canonical-name>\"` (a source alias) instead of a second `[registries.<name>]` with the same index.","Unset any `CARGO_REGISTRIES_<NAME>_INDEX` env var that duplicates a config entry's URL.","Run `cargo config get registries` to list all configured registries and identify the collision."],"exampleFix":"# before: two registries, same index\n[registries.mirror]\nindex = \"sparse+https://crates.io/index/\"\n[registries.upstream]\nindex = \"sparse+https://crates.io/index/\"\n\n# after: alias via source, single registry\n[registries.mirror]\nindex = \"sparse+https://crates.io/index/\"\n[source.upstream]\nregistry = \"mirror\"","handlingStrategy":"validation","validationCode":"fn registries_unique_indexes(config: &toml::Value) -> Result<(), anyhow::Error> {\n    let mut seen = std::collections::HashSet::new();\n    if let Some(regs) = config.get(\"registries\").and_then(|v| v.as_table()) {\n        for (name, v) in regs {\n            if let Some(idx) = v.get(\"index\").and_then(|s| s.as_str()) {\n                if !seen.insert(idx.to_string()) {\n                    anyhow::bail!(\"duplicate index across registries: {idx} (at {name})\");\n                }\n            }\n        }\n    }\n    Ok(())\n}","typeGuard":"fn registry_indexes_unique(config: &toml::Value) -> bool {\n    let mut s = std::collections::HashSet::new();\n    config.get(\"registries\").and_then(|v| v.as_table()).map_or(true, |t|\n        t.values().filter_map(|v| v.get(\"index\").and_then(|i| i.as_str())).all(|i| s.insert(i.to_string())))\n}","tryCatchPattern":"match auth::registry_name_from_sid(&sid, gctx) {\n    Ok(name) => Ok(name),\n    Err(e) if e.to_string().contains(\"same index url\") => {\n        // guide user to dedupe; fall back to explicit --registry <name>\n        Err(anyhow!(\"resolve the registry collision by passing --registry explicitly or removing the duplicate config\"))\n    }\n    Err(e) => Err(e),\n}","preventionTips":["Use `[source.<alias>] registry = \"<name>\"` to alias, not duplicate `[registries.*]`.","Audit `.cargo/config.toml` for duplicate index URLs.","Unset redundant `CARGO_REGISTRIES_<NAME>_INDEX` env vars.","Pass `--registry <name>` explicitly to disambiguate when needed."],"tags":["cargo","registry","configuration","auth","ambiguous","credentials"],"backgroundTag":null,"analyzedSha":"98a09e7e7d62850f14e5b6132101fc1edd19a16f","analyzedAt":"2026-08-11T17:42:36.556Z","contentChangedAt":"2026-08-11T17:42:36.556Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}