rust-lang/cargo · error · anyhow::Error

local registry path is not a directory: {}

Error message

local registry path is not a directory: {}

What it means

A local (directory-based) registry's root path must be an existing directory. `LocalRegistry::update` (src/sources/registry/local.rs:96) checks `root.is_dir()` and bails if the configured root is missing, is a file, or is otherwise not a directory. Local registries are read directly from disk, so a non-directory root is fatal.

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 0e07a15537)

Solutions

  1. Verify the path exists and is a directory: `ls -la <path>`; create or fix it if missing.
  2. Use an absolute path in `.cargo/config.toml` to avoid working-directory ambiguity.
  3. Ensure the directory follows the local-registry layout (an `index/` subdir and per-crate `.crate` files).

Example fix

# before
[source.my-local]
local-registry = "vendor"   # 'vendor' is a file or missing -> error

# after: ensure it is an existing directory with the right layout
mkdir -p vendor/index
# (populate vendor/index and vendor/*.crate)
[source.my-local]
local-registry = "/abs/path/to/vendor"
Defensive patterns

Strategy: validation

Validate before calling

// Validate local-registry root before handing it to Cargo.
fn valid_local_registry_root(p: &Path) -> bool { p.is_dir() }

Type guard

pub fn is_local_registry_ready(p: &Path) -> bool {
    p.is_dir() && p.join("index").is_dir()
}

Prevention

When it happens

Trigger: Configuring `[source.<name>]` with `local-registry = "path"` where `path` doesn't exist or is a file; relative path resolved against an unexpected working directory; the registry directory was deleted/moved after being referenced.

Common situations: Vendoring-style setups pointing at a path that wasn't created; typo in the path; running cargo from a different directory than the config assumed (relative path); CI checkout missing the registry directory.

Related errors


AI-assisted analysis of rust-lang/cargo@0e07a15537 (2026-08-06). Data as JSON: /data/errors/32573c3e648ec587.json. Report an issue: GitHub.