rust-lang/cargo · error
failed to find rmeta
Error message
failed to find rmeta
What it means
While checking staleness, the fingerprint code selects the `.rmeta` output from a dependency's mtimes via `.find(...).expect("failed to find rmeta")` when `dep.only_requires_rmeta` is true. The dependency's outputs are expected to contain an `.rmeta` file; the panic means none of the recorded output paths has the `rmeta` extension.
Source
Thrown at src/compiler/fingerprint/mod.rs:1310
| FsStatus::StaleDependency { .. }
| FsStatus::StaleDepFingerprint { .. } => {
self.fs_status = FsStatus::StaleDepFingerprint {
unit: dep.fingerprint.index,
};
return Ok(());
}
};
// If our dependency edge only requires the rmeta file to be present
// then we only need to look at that one output file, otherwise we
// need to consider all output files to see if we're out of date.
let (dep_path, dep_mtime) = if dep.only_requires_rmeta {
dep_mtimes
.iter()
.find(|(path, _mtime)| {
path.extension().and_then(|s| s.to_str()) == Some("rmeta")
})
.expect("failed to find rmeta")
} else {
match dep_mtimes.iter().max_by_key(|kv| kv.1) {
Some(dep_mtime) => dep_mtime,
// If our dependencies is up to date and has no filesystem
// interactions, then we can move on to the next dependency.
None => continue,
}
};
debug!(
"max dep mtime for {:?} is {:?} {}",
pkg_root, dep_path, dep_mtime
);
// If the dependency is newer than our own output then it was
// recompiled previously. We transitively become stale ourselves in
// that case, so bail out.
//
// Note that this comparison should probably be `>=`, not `>`, butView on GitHub (pinned to 0e07a15537)
Solutions
- `cargo clean` and rebuild — missing `.rmeta` is almost always a stale/corrupt `target/`.
- Ensure no external process deletes files under `target/` (antivirus, backup tools, IDE cleanup).
- Free disk space if `target/` ran out of inodes/space mid-build.
Example fix
// before
let (dep_path, dep_mtime) = if dep.only_requires_rmeta {
dep_mtimes
.iter()
.find(|(path, _mtime)| path.extension().and_then(|s| s.to_str()) == Some("rmeta"))
.expect("failed to find rmeta")
};
// after
let (dep_path, dep_mtime) = if dep.only_requires_rmeta {
dep_mtimes
.iter()
.find(|(path, _mtime)| path.extension().and_then(|s| s.to_str()) == Some("rmeta"))
.ok_or_else(|| anyhow::anyhow!("dependency marked only_requires_rmeta has no .rmeta output"))?
}; Defensive patterns
Strategy: validation
Validate before calling
// Confirm the target dir still contains .rmeta files before incremental rebuilds
fn has_rmeta(target_deps: &std::path::Path) -> bool {
walkdir::WalkDir::new(target_deps).into_iter().filter_map(Result::ok)
.any(|e| e.path().extension().and_then(|s| s.to_str()) == Some("rmeta"))
} Prevention
- `cargo clean` whenever you switch rustc versions.
- Exclude `target/` from antivirus/backup/IDE cleanup.
- Ensure adequate free disk space and inodes.
When it happens
Trigger: A dependency edge marked `only_requires_rmeta` whose compiled outputs were stripped of the `.rmeta` (e.g. it was built with a mode that emits only an rlib, or the file was deleted between Cargo recording it and the fingerprint check); pipelined compilation where the rmeta was never produced (rustc failed) but the unit was marked fresh.
Common situations: `cargo clean`/file deletion racing with a build; switching rustc versions without cleaning (rmeta emission rules changed); disk-full or antivirus quarantine removing `.rmeta` files from `target/`.
Related errors
- failed to find rmeta dep for pipelined dep
- output must exist after running
- artifact-dir was not locked
- required(true)
- a file should always have a parent
AI-assisted analysis of rust-lang/cargo@0e07a15537 (2026-08-06).
Data as JSON: /data/errors/e5b5801936036f2b.json.
Report an issue: GitHub.