rust-lang/cargo · error · anyhow::Error
unable to read .cargo-ok file at {path:?}: {e}
Error message
unable to read .cargo-ok file at {path:?}: {e} What it means
Before unpacking a `.crate`, Cargo reads its `.cargo-ok` marker file (src/sources/registry/mod.rs:562). A `NotFound` IO error is expected and ignored (meaning 'unpack fresh'), but any *other* IO error (permission denied, disk error, broken symlink) is fatal and reported with this message including `{path:?}` and the underlying `{e}`. This protects against silently treating an unreadable cache as 'not yet unpacked'.
Source
Thrown at src/sources/registry/mod.rs:585
.mark_registry_src_used(global_cache_tracker::RegistrySrc {
encoded_registry_name: self.name,
package_dir: package_dir.into(),
size: None,
});
return Ok(unpack_dir.to_path_buf());
}
_ => {
if ok == "ok" {
tracing::debug!("old `ok` content found, clearing cache");
} else {
tracing::warn!("unrecognized .cargo-ok content, clearing cache: {ok}");
}
// See comment of `unpack_package` about why removing all stuff.
paths::remove_dir_all(dst.as_path_unlocked())?;
}
},
Err(e) if e.kind() == io::ErrorKind::NotFound => {}
Err(e) => anyhow::bail!("unable to read .cargo-ok file at {path:?}: {e}"),
}
dst.create_dir()?;
let bytes_written = unpack(self.gctx, tarball, unpack_dir, &|_| true)?;
update_mtime_for_generated_files(unpack_dir);
// Now that we've finished unpacking, create and write to the lock file to indicate that
// unpacking was successful.
let mut ok = OpenOptions::new()
.create_new(true)
.read(true)
.write(true)
.open(&path)
.with_context(|| format!("failed to open `{}`", path.display()))?;
let lock_meta = LockMetadata { v: 1 };
write!(ok, "{}", serde_json::to_string(&lock_meta).unwrap())?;
View on GitHub (pinned to 0e07a15537)
Solutions
- Inspect the exact `{path}` from the message and check permissions/ownership: `ls -la <dir>`.
- Fix ownership/permissions (`chown`/`chmod`) or remove the corrupted unpacked package directory so Cargo re-unpacks.
- If the disk/filesystem is failing, run `fsck` / move `CARGO_HOME` to healthy storage.
Example fix
# before: .cargo-ok unreadable (wrong owner) sudo chown -R $USER:$USER ~/.cargo # or just evict the bad unpack cargo cache --autoclean # / rm -rf ~/.cargo/registry/src/<reg>/<pkg>-<ver>
Defensive patterns
Strategy: validation
Validate before calling
// If you manipulate ~/.cargo programmatically, ensure .cargo-ok is readable.
fn cargo_ok_readable(p: &Path) -> bool {
match std::fs::read_to_string(p) {
Ok(_) => true,
Err(e) if e.kind() == std::io::ErrorKind::NotFound => true, // expected
Err(_) => false,
}
} Prevention
- Run cargo as a single user; avoid `sudo`/ownership flips under `~/.cargo`.
- Don't symlink `.cargo-ok` to unreadable targets.
- Periodically clear corrupted unpack dirs with `cargo cache --autoclean`.
When it happens
Trigger: The `.cargo-ok` file exists but can't be read due to permissions (`EACCES`), a broken symlink, a filesystem I/O error, or a race where the file/dir was removed mid-operation with a non-NotFound error.
Common situations: `chmod`/ownership changes under `~/.cargo/registry/src/`; a broken symlink left by a failed sync; disk/filesystem corruption; SELinux/AppArmor denying reads; running as a different user than the one that created the cache.
Related errors
- failed to read path `{path:?}`
- failed to open `{}`: {}
- local registry path is not a directory: {}
- local registry index path is not a directory: {}
- {err}
AI-assisted analysis of rust-lang/cargo@0e07a15537 (2026-08-06).
Data as JSON: /data/errors/ea6580d267e3b020.json.
Report an issue: GitHub.