rust-lang/cargo · warning · anyhow::Error
failed to read path `{path:?}`
Error message
failed to read path `{path:?}` What it means
Raised in `GlobalCacheTracker::read_dir_with_filter` (src/workspace/global_cache_tracker.rs:680) when `path.read_dir()` fails with an io::Error whose kind is NOT `NotFound` (NotFound is tolerated and returns an empty vec). Any other IO failure — permission denied, broken symlink, I/O error — is wrapped with `failed to read path \"<path>\"` context.
Source
Thrown at src/workspace/global_cache_tracker.rs:681
fn list_dir_names(path: &Path) -> CargoResult<Vec<String>> {
Self::read_dir_with_filter(path, &|entry| {
entry.file_type().map_or(false, |ty| ty.is_dir())
})
}
/// Returns a list of names in a directory, filtered by the given callback.
fn read_dir_with_filter(
path: &Path,
filter: &dyn Fn(&std::fs::DirEntry) -> bool,
) -> CargoResult<Vec<String>> {
let entries = match path.read_dir() {
Ok(e) => e,
Err(e) => {
if e.kind() == std::io::ErrorKind::NotFound {
return Ok(Vec::new());
} else {
return Err(
anyhow::Error::new(e).context(format!("failed to read path `{path:?}`"))
);
}
}
};
let names = entries
.filter_map(|entry| entry.ok())
.filter(|entry| filter(entry))
.filter_map(|entry| entry.file_name().into_string().ok())
.collect();
Ok(names)
}
/// Synchronizes the database to match the files on disk.
///
/// This performs the following cleanups:
///
/// 1. Remove entries from the database that are missing on disk.
/// 2. Adds missing entries to the database that are on disk (such as whenView on GitHub (pinned to 0e07a15537)
Solutions
- Fix permissions so cargo can read the directory (`chmod -R u+rX ~/.cargo`).
- Remove broken symlinks or corrupt cache entries (`cargo cache clean` or manual cleanup of the named path).
- Ensure no other process is mutating `$CARGO_HOME` while cargo runs; retry if it was transient (I/O error).
Example fix
# grant read+execute on the offending cache dir chmod -R u+rX ~/.cargo/registry/cache # or clean a corrupt cache cargo cache clean
Defensive patterns
Strategy: try-catch
Validate before calling
use std::path::Path;
fn readable_dir(p: &Path) -> bool {
match std::fs::metadata(p) {
Ok(m) => m.is_dir() && std::fs::read_dir(p).is_ok(),
Err(_) => false,
}
}
// before cache operations, verify readable_dir on $CARGO_HOME subdirs Try / catch
// treat non-NotFound read_dir errors as best-effort skips
let names = match path.read_dir() {
Ok(e) => e.filter_map(|r| r.ok()).map(|e| e.file_name().to_string_lossy().into_owned()).collect::<Vec<_>>(),
Err(e) if e.kind() == std::io::ErrorKind::NotFound => Vec::new(),
Err(_) => Vec::new(), // swallow permission/IO errors instead of failing
}; Prevention
- Run cargo as the owner of $CARGO_HOME; fix permissions with chmod -R u+rX.
- Avoid concurrent mutating access to the cargo cache.
- Periodically clean corrupt cache entries.
When it happens
Trigger: `cargo cache` / global cache tracking walks a directory under `$CARGO_HOME` (e.g. `registry/cache`, `git/db`) and `read_dir` returns a non-NotFound error: EACCES on a dir cargo cannot traverse, EIO, a broken symlink target, or a filesystem error.
Common situations: Permissions on `~/.cargo` set so some subdirs are not readable by the cargo user; partial extraction leaving broken symlinks; NFS/share hiccups; another process modifying the cache concurrently; disk errors.
Related errors
- unable to read .cargo-ok file at {path:?}: {e}
- failed to open `{}`: {}
- {err}
- cache expected 4 bytes for index schema version
- registry said cache valid when no cache exists
AI-assisted analysis of rust-lang/cargo@0e07a15537 (2026-08-06).
Data as JSON: /data/errors/dd14c5d606f98645.json.
Report an issue: GitHub.