{"record":{"id":"1a64f0fef4bd106d","repo":"rust-lang/cargo","slug":"unsupported-registry-protocol-unknown-defined","errorCode":null,"errorMessage":"unsupported registry protocol `{unknown}` (defined in {})","messagePattern":"unsupported registry protocol `(.+?)` \\(defined in (.+?)\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/workspace/source_id.rs","lineNumber":287,"sourceCode":"    pub fn crates_io_maybe_sparse_http(gctx: &GlobalContext) -> CargoResult<SourceId> {\n        if Self::crates_io_is_sparse(gctx)? {\n            gctx.check_registry_index_not_set()?;\n            let url = CRATES_IO_HTTP_INDEX.into_url().unwrap();\n            let key = KeyOf::Registry(CRATES_IO_REGISTRY.into());\n            SourceId::new(SourceKind::SparseRegistry, url, Some(key))\n        } else {\n            Self::crates_io(gctx)\n        }\n    }\n\n    /// Returns whether to access crates.io over the sparse protocol.\n    pub fn crates_io_is_sparse(gctx: &GlobalContext) -> CargoResult<bool> {\n        let proto: Option<context::Value<String>> =\n            gctx.get([\"registries\", \"crates-io\", \"protocol\"])?;\n        let is_sparse = match proto.as_ref().map(|v| v.val.as_str()) {\n            Some(\"sparse\") => true,\n            Some(\"git\") => false,\n            Some(unknown) => anyhow::bail!(\n                \"unsupported registry protocol `{unknown}` (defined in {})\",\n                proto.as_ref().unwrap().definition\n            ),\n            None => true,\n        };\n        Ok(is_sparse)\n    }\n\n    /// Gets the `SourceId` associated with given name of the remote registry.\n    pub fn alt_registry(gctx: &GlobalContext, key: &str) -> CargoResult<SourceId> {\n        if key == CRATES_IO_REGISTRY {\n            return Self::crates_io(gctx);\n        }\n        let url = gctx.get_registry_index(key)?;\n        Self::for_alt_registry(&url, key)\n    }\n\n    /// Gets this source URL.","sourceCodeStart":269,"sourceCodeEnd":305,"githubUrl":"https://github.com/rust-lang/cargo/blob/98a09e7e7d62850f14e5b6132101fc1edd19a16f/src/workspace/source_id.rs#L269-L305","documentation":"Cargo validates the `registries.crates-io.protocol` configuration key when deciding how to access crates.io. The matcher accepts only three outcomes: the literal string `sparse` (returns true), the literal string `git` (returns false), or an unset/None value (defaults to sparse). Any other string value reaches the `Some(unknown)` arm and is rejected. The error message interpolates both the offending value and the config definition location so the user can find where it was set.","triggerScenarios":"Calling `SourceId::crates_io_is_sparse(gctx)` after Cargo reads `registries.crates-io.protocol` from config. Triggered when the resolved `context::Value<String>` is `Some(s)` where `s` is neither `\"sparse\"` nor `\"git\"` (e.g. `\"http\"`, `\"sparse-registry\"`, `\"https\"`, or a typo).","commonSituations":"Typos in `.cargo/config.toml` (e.g. `protocol = \"sparse-registry\"` instead of `\"sparse\"`), using values valid in a newer/older Cargo on an incompatible version, copying config snippets from outdated documentation, or setting the key via environment-driven config layers to an unsupported token.","solutions":["Set `registries.crates-io.protocol` to either `\"sparse\"` or `\"git\"` in your config file, matching Cargo's accepted vocabulary.","Remove the `registries.crates-io.protocol` key entirely to fall back to the default (sparse) behavior.","Inspect every config definition site printed in the error message (`defined in {}`) to find which file layer supplies the bad value, including `~/.cargo/config.toml`, project `.cargo/config.toml`, and env config overrides."],"exampleFix":"// before (in .cargo/config.toml)\n[registries.crates-io]\nprotocol = \"sparse-registry\"\n\n// after\n[registries.crates-io]\nprotocol = \"sparse\"","handlingStrategy":"validation","validationCode":"fn valid_protocol(p: &str) -> bool { matches!(p, \"sparse\" | \"git\") }\n// before reading config, validate the intended value\nlet proto: String = /* user/intended value */;\nassert!(valid_protocol(&proto), \"protocol must be 'sparse' or 'git'\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat `registries.crates-io.protocol` as an enum of two literals; validate at config-authoring time.","Keep a single source of truth for the value and lint it in CI.","When upgrading Cargo, diff your `.cargo/config.toml` against the version's accepted keys."],"tags":["config","registry","cargo","crates-io","validation"],"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"}