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

registry said cache valid when no cache exists

Error message

registry said cache valid when no cache exists

What it means

When loading a crate summary, Cargo first checks its on-disk cache and sends the cached `index_version` to the backend; if the backend responds `LoadResponse::CacheValid` (meaning 'your cache is current') but Cargo has no cached summary at all, it bails (src/sources/registry/index/mod.rs:552). A backend must only claim cache-validity relative to a version the client actually holds.

Source

Thrown at src/sources/registry/index/mod.rs:555

                Ok((s, v)) => {
                    cached_summaries = Some(s);
                    index_version = Some(v);
                }
                Err(e) => {
                    tracing::debug!("failed to parse {lowered_name:?} cache: {e}");
                }
            }
        }

        let response = load
            .load(root, relative.as_ref(), index_version.as_deref())
            .await?;

        match response {
            LoadResponse::CacheValid => {
                tracing::debug!("fast path for registry cache of {:?}", relative);
                if cached_summaries.is_none() {
                    return Err(anyhow::anyhow!(
                        "registry said cache valid when no cache exists"
                    ));
                }
                return Ok(cached_summaries);
            }
            LoadResponse::NotFound => {
                cache_manager.invalidate(lowered_name);
                return Ok(None);
            }
            LoadResponse::Data {
                raw_data,
                index_version,
            } => {
                // This is the fallback path where we actually talk to the registry backend to load
                // information. Here we parse every single line in the index (as we need
                // to find the versions)
                tracing::debug!("slow path for {:?}", relative);
                let mut cache = SummariesCache::default();

View on GitHub (pinned to 0e07a15537)

Solutions

  1. Delete the registry cache for that crate/registry and retry: `rm -rf ~/.cargo/registry/index/<reg>/`.
  2. If you maintain a custom `RegistryData` impl, only return `CacheValid` when you were actually passed a non-`None` `index_version` AND you can confirm the client holds that version.
  3. Ensure no other process is mutating `~/.cargo/registry/` concurrently (Cargo uses file locks; external cleaners bypass them).
Defensive patterns

Strategy: validation

Validate before calling

// Custom RegistryData impls: only claim CacheValid when a cache actually exists.
async fn load(&self, root: &Path, path: &Path, index_version: Option<&str>) -> CargoResult<LoadResponse> {
    if let Some(v) = index_version {
        if !self.cache_exists(path)? { return Ok(LoadResponse::Data { /* ... */ }); }
        if v == self.server_version(path)? { return Ok(LoadResponse::CacheValid); }
    }
    // ... fetch fresh
}

Prevention

When it happens

Trigger: A registry backend (`load` impl) returns `CacheValid` while the caller's `cached_summaries` is `None` — i.e. an inconsistency between 'do you have a cache?' and 'is it valid?'. Typically a bug in a custom `RegistryData` implementation, or a state-machine glitch where the cache file was deleted between the version check and the load.

Common situations: Custom/alternative registry backends with a buggy `load()` that returns `CacheValid` unconditionally; concurrent processes deleting the cache file mid-operation; a corrupt cache that failed to parse (so `cached_summaries` is None) yet the backend still says valid.

Related errors


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