rust-lang/cargo · error

override found but no real ones

Error message

override found but no real ones

What it means

An internal consistency error in the registry's lock/override logic: a path-override summary (`override_summary`) exists for a dependency, but the underlying source (`self.sources`) has no matching entry (`source` is `None`). This indicates the override references a source Cargo can no longer locate — typically a stale lock file or a removed/renamed override path.

Solutions

  1. Run `cargo update` to regenerate the lock file against the current manifest.
  2. Verify the override path still exists and is accessible.
  3. Remove stale `[replace]` entries or path overrides from the manifest.

Example fix

# before: lock file references a removed override
# (run:) cargo update

# after: lock file regenerated, override reconciled with current sources
Defensive patterns

Strategy: retry

Validate before calling

// Verify override sources are present before resolving
fn override_sources_exist(sources: &[&SourceId], registry: &SourceMap) -> bool {
    sources.iter().all(|sid| registry.get(sid).is_some())
}

Try / catch

// if cargo fails with "override found but no real ones":
//   1. cargo update  // regenerate lock
//   2. if persists, delete Cargo.lock and cargo generate-lockfile

Prevention

When it happens

Trigger: The `(Some(_), None)` arm at registry.rs:745-747 fires: an override summary was produced by `[replace]`/path override logic, but the source registry has no entry for `dep.source_id()`.

Common situations: A lock file referencing a path override whose directory was deleted or moved. Removing a `[replace]` section without regenerating the lock. Switching branches with divergent override configs.

Related errors


AI-assisted analysis of rust-lang/cargo@98a09e7e7d (2026-08-11). Data as JSON: /api/errors/b1dbeb0db3c14229. Report an issue: GitHub.

Appendix: source

Thrown at src/workspace/registry.rs:756

            kind: QueryKind,
            f: &mut dyn FnMut(IndexSummary),
        ) -> CargoResult<()> {
            source
                .query(dep, kind, f)
                .await
                .with_context(|| format!("unable to update {}", source.source_id()))
                .with_context(|| {
                    format!(
                        "failed to load source for dependency `{}`",
                        dep.package_name()
                    )
                })
        }

        let source = self.sources.borrow().get(dep.source_id()).cloned();
        match (override_summary, source) {
            (Some(_), None) => {
                return Err(anyhow::anyhow!("override found but no real ones"));
            }
            (None, None) => return Ok(()),

            // If we don't have an override then we just ship everything upstairs after locking the summary
            (None, Some(source)) => {
                for patch in patches.iter() {
                    f(IndexSummary::Candidate(patch.clone()));
                }

                // Our sources shouldn't ever come back to us with two summaries
                // that have the same version. We could, however, have an `[patch]`
                // section which is in use to override a version in the registry.
                // This means that if our `summary` in this loop has the same
                // version as something in `patches` that we've already selected,
                // then we skip this `summary`.
                let locked = &self.locked;
                let all_patches = &self.patches_available;
                let mode = if self.gctx.cli_unstable().prerelease {

View on GitHub (pinned to 98a09e7e7d)