rust-lang/cargo · error · anyhow::Error
failed to open
Error message
failed to open `{}`: {} What it means
Thrown by cargo_clean when fs::File::open on target/CACHEDIR.TAG fails, after earlier checks already confirmed the path is a regular non-symlink file. The format string interpolates the path and the underlying io::Error, so this is an OS-level open failure (permissions, race with deletion, filesystem error) rather than a missing-file mistake, which is caught earlier.
Solutions
- Re-run `cargo clean` with no concurrent cargo process active.
- Check ownership and permissions of target/CACHEDIR.TAG and fix with chmod/chown if owned by another user.
- If the filesystem is read-only or sandboxed, remount writable or relax the sandbox for the target dir.
- As a last resort, remove the target directory manually: `rm -rf target`.
Example fix
# before (target owned by root from a sudo build) cargo clean # after sudo chown -R $USER:$USER target && cargo clean
Defensive patterns
Strategy: try-catch
Validate before calling
// Verify target dir is cleanable before invoking cargo clean.
use std::os::unix::fs::PermissionsExt;
fn writable(p: &std::path::Path) -> bool {
std::fs::metadata(p).map(|m| m.permissions().mode() & 0o200 != 0).unwrap_or(false)
} Try / catch
// Wrap cargo clean invocations and fall back to manual removal on open failure.
match std::process::Command::new("cargo").arg("clean").status() {
Ok(s) if s.success() => {},
_ => { let _ = std::fs::remove_dir_all("target"); }
} Prevention
- Do not run `cargo clean` concurrently with builds.
- Ensure the target directory is owned by the invoking user.
- On CI, prefer a fresh workspace over cleaning a shared one.
When it happens
Trigger: Another process deletes target/ between the is_file() check and the open() call; file permissions deny read access to the current user; a read-only filesystem mount; antivirus/container sandbox blocking open; CACHEDIR.TAG exists but is held exclusively on Windows.
Common situations: Running `cargo clean` while a build or IDE is concurrently writing to target/; CI runners with restricted perms; NFS/network filesystems with stale file handles; switched user / sudo leaving target owned by root.
Related errors
- unable to read .cargo-ok file at
- failed to read path
- artifact-dir was not locked during clean
- can only edit absolute paths, got
- can't find library ` `, rename file to `src/lib.rs` or…
AI-assisted analysis of rust-lang/cargo@98a09e7e7d (2026-08-11).
Data as JSON: /api/errors/68e9219d2df02a72.
Report an issue: GitHub.
Appendix: source
Thrown at src/ops/cargo_clean.rs:172
Ok(())
}
fn validate_target_dir_tag(target_dir_path: &Path) -> CargoResult<()> {
const TAG_SIGNATURE: &[u8] = b"Signature: 8a477f597d28d172789f06886806bc55";
let tag_path = target_dir_path.join("CACHEDIR.TAG");
// per https://bford.info/cachedir the tag file must not be a symlink
if tag_path.is_symlink() {
bail!("expect `CACHEDIR.TAG` to be a regular file, got a symlink");
}
if !tag_path.is_file() {
bail!("missing or invalid `CACHEDIR.TAG` file");
}
let mut file = fs::File::open(&tag_path)
.map_err(|err| anyhow::anyhow!("failed to open `{}`: {}", tag_path.display(), err))?;
let mut buf = [0u8; TAG_SIGNATURE.len()];
match file.read_exact(&mut buf) {
Ok(()) if &buf[..] == TAG_SIGNATURE => {}
Err(e) if e.kind() != io::ErrorKind::UnexpectedEof => {
bail!("failed to read `{}`: {e}", tag_path.display());
}
_ => {
bail!("invalid signature in `CACHEDIR.TAG` file");
}
}
Ok(())
}
fn clean_specs(
clean_ctx: &mut CleanContext<'_>,
ws: &Workspace<'_>,View on GitHub (pinned to 98a09e7e7d)