rust-lang/cargo · error
local registry path is not a directory
Error message
local registry path is not a directory: {} What it means
A local registry (`registry = "file://..."` style source) requires its root directory to exist on disk. During `update()`, Cargo checks `root.is_dir()`; if the path is missing or is a file, it bails. Local registries serve pre-populated index + `.crate` files from the filesystem (no network), so the directory must exist.
Solutions
- Verify the path exists and is a directory: `ls -la <path>`.
- Fix the configured path in `.cargo/config.toml` / `Cargo.toml` to the correct absolute location.
- Populate the local registry (vendor the index and `.crate` files) before building.
- Use an absolute path to avoid working-directory ambiguity.
Example fix
# before [source.mylocal] registry = "file:///opt/cargo-registry" # missing # after [source.mylocal] registry = "file:///srv/cargo-registry" # exists and is a dir
Defensive patterns
Strategy: validation
Validate before calling
fn ensure_local_registry_root(root: &Path) -> Result<(), anyhow::Error> {
if !root.is_dir() { anyhow::bail!("local registry root is not a directory: {}", root.display()); }
Ok(())
} Type guard
fn local_registry_root_exists(root: &std::path::Path) -> bool { root.is_dir() } Try / catch
if !root.is_dir() {
// attempt to mount/populate, else surface actionable message
return Err(anyhow!("local registry path missing: {}; vendor or fix config", root.display()));
} Prevention
- Use absolute paths for local registries.
- Vendor the registry before building (`cargo vendor`).
- CI: verify the local registry path is mounted before `cargo build`.
- Lint config for moved/non-existent local registry paths.
When it happens
Trigger: A `[source.<name>]` or dependency configured with `registry =` pointing at a local filesystem path that does not exist or is not a directory. Reached on the first `update()` of a `LocalRegistry`.
Common situations: Path moved/renamed since config was written; relative path interpreted from a different working directory; local registry never vendored into place; typo in the `file://` URL; build server missing the mounted registry volume.
Related errors
- local registry index path is not a directory
- config.json not found
- failed to verify the checksum of
- multiple registries are configured with the same index url
- path ` ` is not a blob in the git repo
AI-assisted analysis of rust-lang/cargo@eb98b54bc9 (2026-08-11).
Data as JSON: /api/errors/32573c3e648ec587.
Report an issue: GitHub.
Appendix: source
Thrown at src/sources/registry/local.rs:97
src_path: gctx.registry_source_path().join(name),
index_path: Filesystem::new(root.join("index")),
root: Filesystem::new(root.to_path_buf()),
gctx,
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(())
}View on GitHub (pinned to eb98b54bc9)