rust-lang/cargo · error · anyhow::Error
local registry index path is not a directory: {}
Error message
local registry index path is not a directory: {} What it means
Even when a local registry root exists, Cargo additionally requires an `index/` subdirectory inside it (src/sources/registry/local.rs:100). If `root/index` is missing or is not a directory, it bails. The index directory is where Cargo reads the JSON-line metadata for each crate.
Source
Thrown at src/sources/registry/local.rs:101
updated: Cell::new(false),
quiet: false,
}
}
fn update(&self) -> CargoResult<()> {
if self.updated.get() {
return Ok(());
}
// Nothing to update, we just use what's on disk. Verify it actually
// exists though. We don't use any locks as we're just checking whether
// these directories exist.
let root = self.root.clone().into_path_unlocked();
if !root.is_dir() {
anyhow::bail!("local registry path is not a directory: {}", root.display());
}
let index_path = self.index_path.clone().into_path_unlocked();
if !index_path.is_dir() {
anyhow::bail!(
"local registry index path is not a directory: {}",
index_path.display()
);
}
self.updated.set(true);
Ok(())
}
}
#[async_trait::async_trait(?Send)]
impl<'gctx> RegistryData for LocalRegistry<'gctx> {
fn prepare(&self) -> CargoResult<()> {
Ok(())
}
fn index_path(&self) -> &Filesystem {
&self.index_path
}View on GitHub (pinned to 0e07a15537)
Solutions
- Confirm `root/index` exists and is a directory; create it and populate it with the proper JSON-line index files if missing.
- Regenerate the local registry with a tool that produces the correct layout (e.g. `cargo vendor` for vendored sources, or the documented local-registry format).
- Check that nothing (a build step, `.gitignore`) deleted the index directory.
Example fix
# before: root exists but index/ missing
my-registry/
foo-1.0.0.crate
# after
my-registry/
index/
fo/o/foo # JSON-line index entry
foo-1.0.0.crate Defensive patterns
Strategy: validation
Validate before calling
// Check both root and index/ exist as directories.
fn valid_local_registry(p: &Path) -> bool {
p.is_dir() && p.join("index").is_dir()
} Type guard
pub fn is_local_registry_ready(p: &Path) -> bool {
p.is_dir() && p.join("index").is_dir()
} Prevention
- Generate local registries with a tool that produces the documented layout (`index/` subdir + `.crate` files).
- Add a CI check that asserts the local-registry directory structure before invoking cargo.
When it happens
Trigger: A local-registry root that exists but lacks the `index/` subdir; `index` exists but is a regular file; a partially-set-up vendor directory.
Common situations: Hand-creating a local registry without the index; a vendoring tool that wrote `.crate` files but not the index; renaming/moving the index directory; typo in the layout.
Related errors
- local registry path is not a directory: {}
- config.json not found
- sparse registry url must end in a slash `/`: {url}
- failed to verify the checksum of `{}`
- unable to read .cargo-ok file at {path:?}: {e}
AI-assisted analysis of rust-lang/cargo@0e07a15537 (2026-08-06).
Data as JSON: /data/errors/63d2bdb080b77e1c.json.
Report an issue: GitHub.