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

  1. Confirm `root/index` exists and is a directory; create it and populate it with the proper JSON-line index files if missing.
  2. 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).
  3. 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

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


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