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

path `{}` is not a blob in the git repo

Error message

path `{}` is not a blob in the git repo

What it means

When reading a crate's metadata from the git-based registry index, `GitRegistry::load_helper` (src/sources/registry/git_remote.rs:344) resolves the tree entry at `path` and asserts it is a `Blob`. If `entry.to_object(repo).as_blob()` returns `None` (the object is a tree, commit, submodule, or tag object instead), Cargo bails. The index is expected to store one JSON-line blob per crate path, so a non-blob indicates a malformed/corrupt index.

Source

Thrown at src/sources/registry/git_remote.rs:356

            registry: &GitRegistry<'_>,
            path: &Path,
            index_version: Option<&str>,
        ) -> CargoResult<LoadResponse> {
            let repo = registry.repo()?;
            let repo = repo.as_ref().unwrap();
            let tree = registry.tree()?;
            let entry = tree.get_path(path);
            let entry = entry?;
            let git_file_hash = Some(entry.id().to_string());

            // Check if the cache is valid.
            if index_version.is_some() && index_version == git_file_hash.as_deref() {
                return Ok(LoadResponse::CacheValid);
            }

            let object = entry.to_object(repo)?;
            let Some(blob) = object.as_blob() else {
                anyhow::bail!("path `{}` is not a blob in the git repo", path.display())
            };

            Ok(LoadResponse::Data {
                raw_data: blob.content().to_vec(),
                index_version: git_file_hash,
            })
        }

        loop {
            return match load_helper(&self, path, index_version) {
                Ok(result) => Ok(result),
                Err(_) if !self.is_updated() => {
                    // If git returns an error and we haven't updated the repo,
                    // return pending to allow an update to try again.
                    self.needs_update.set(true);
                    self.update()?;
                    continue;
                }

View on GitHub (pinned to 0e07a15537)

Solutions

  1. Force a clean re-clone of the registry index: remove `~/.cargo/registry/index/<registry-name>/` and run `cargo fetch`.
  2. If you operate the registry, audit the index repository for entries that are directories/submodules instead of JSON-line blobs at the offending path.
  3. Verify the index isn't a shallow/partial clone (the error-recovery path at line 368 already retries after an update; if it persists the index content itself is wrong).
Defensive patterns

Strategy: validation

Prevention

When it happens

Trigger: A registry index git repository whose path entry for a crate resolves to a directory (tree) or a submodule rather than a file — e.g. a hand-rolled/misbuilt private registry that committed a folder instead of a file, or a corrupt/shallow clone of the index. Reached via `load()` in `git_remote.rs`.

Common situations: Custom/private registries built incorrectly (folder where a JSON-line file should be); a partially-cloned or corrupted `~/.cargo/registry/index/` git checkout; an index that added a submodule path colliding with a crate name.

Related errors


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