{"record":{"id":"63d2bdb080b77e1c","repo":"rust-lang/cargo","slug":"local-registry-index-path-is-not-a-directory","errorCode":null,"errorMessage":"local registry index path is not a directory: {}","messagePattern":"local registry index path is not a directory: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/sources/registry/local.rs","lineNumber":101,"sourceCode":"            updated: Cell::new(false),\n            quiet: false,\n        }\n    }\n\n    fn update(&self) -> CargoResult<()> {\n        if self.updated.get() {\n            return Ok(());\n        }\n        // Nothing to update, we just use what's on disk. Verify it actually\n        // exists though. We don't use any locks as we're just checking whether\n        // these directories exist.\n        let root = self.root.clone().into_path_unlocked();\n        if !root.is_dir() {\n            anyhow::bail!(\"local registry path is not a directory: {}\", root.display());\n        }\n        let index_path = self.index_path.clone().into_path_unlocked();\n        if !index_path.is_dir() {\n            anyhow::bail!(\n                \"local registry index path is not a directory: {}\",\n                index_path.display()\n            );\n        }\n        self.updated.set(true);\n        Ok(())\n    }\n}\n\n#[async_trait::async_trait(?Send)]\nimpl<'gctx> RegistryData for LocalRegistry<'gctx> {\n    fn prepare(&self) -> CargoResult<()> {\n        Ok(())\n    }\n\n    fn index_path(&self) -> &Filesystem {\n        &self.index_path\n    }","sourceCodeStart":83,"sourceCodeEnd":119,"githubUrl":"https://github.com/rust-lang/cargo/blob/eb98b54bc9f3c74519f43d066cb3fd02ebc88df0/src/sources/registry/local.rs#L83-L119","documentation":"After validating the local registry root directory exists, Cargo also checks that the `<root>/index` subdirectory exists. If `index_path.is_dir()` is false, it bails. The index directory holds the crates.io-style index tree that a local registry must provide.","triggerScenarios":"Local registry root exists but the `<root>/index` subdirectory is missing or is a file. Reached immediately after the root check passes in `LocalRegistry::update()`.","commonSituations":"Partially-vendored local registry (root created but index omitted); wrong index layout; the `index` path replaced by a file; misconfigured `registries.<name>.index` pointing at a parent that lacks the standard `index/` child.","solutions":["Inspect `<root>` and ensure an `index/` directory exists with the crates.io index layout.","Re-vendor the local registry from source so both root and index are populated.","Point the configuration at the correct registry root that contains `index/`.","Consult the local registry format docs and rebuild the index tree."],"exampleFix":"# before: root exists but index/ missing\n$ ls /srv/cargo-registry\ncache  config.json          # no index/\n\n# after: vendor a proper local registry\n$ ls /srv/cargo-registry\ncache  config.json  index/","handlingStrategy":"validation","validationCode":"fn ensure_local_registry_index(root: &Path) -> Result<(), anyhow::Error> {\n    let idx = root.join(\"index\");\n    if !idx.is_dir() { anyhow::bail!(\"local registry index missing: {}\", idx.display()); }\n    Ok(())\n}","typeGuard":"fn local_registry_index_present(root: &std::path::Path) -> bool { root.join(\"index\").is_dir() }","tryCatchPattern":"if !index_path.is_dir() {\n    return Err(anyhow!(\"index dir missing; re-vendor local registry with index/ subtree\"));\n}","preventionTips":["Vendor complete local registries (root + index + crate files).","Validate the index layout matches crates.io before configuring.","Use `cargo vendor` to produce consistent local registries."],"tags":["cargo","registry","local","filesystem","index","configuration"],"backgroundTag":null,"analyzedSha":"eb98b54bc9f3c74519f43d066cb3fd02ebc88df0","analyzedAt":"2026-08-11T17:42:36.556Z","contentChangedAt":"2026-08-11T17:42:36.556Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}