rust-lang/cargo · error · anyhow::Error

failed to open `{}`: {}

Error message

failed to open `{}`: {}

What it means

A low-level I/O failure while opening the `CACHEDIR.TAG` file inside `validate_target_dir_tag`. `fs::File::open` is mapped to an anyhow error at mod.rs:162 that reports the tag path and the underlying OS error. It surfaces, for example, permission-denied or a dangling path encountered after the existence checks passed.

Source

Thrown at src/ops/cargo_clean.rs:162

    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 0e07a15537)

Solutions

  1. Check permissions on `<dir>/CACHEDIR.TAG` and its parent: ensure the cargo process can read them.
  2. If running in a container/CI, verify the UID/GID matches the directory owner.
  3. Remove the directory manually (`rm -rf <dir>`) if it is safe and let cargo recreate it on the next build.

Example fix

# before
cargo clean --target-dir ./target   # EACCES on CACHEDIR.TAG

# after
sudo chown -R $USER ./target
cargo clean --target-dir ./target
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-check read permission on CACHEDIR.TAG before invoking cargo clean --target-dir.
use std::path::Path;
fn tag_readable(path: &Path) -> bool {
    let tag = path.join("CACHEDIR.TAG");
    std::fs::File::open(&tag).is_ok()
}

Try / catch

// Cargo clean returns a CargoResult; map IO-classified errors to a friendlier message.
match ops::clean(&ws, &opts) {
    Ok(()) => {},
    Err(e) if e.to_string().contains("failed to open") => {
        eprintln!("target dir not readable; check permissions on {}", opts_dir.display());
        return Err(e);
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: `cargo clean --target-dir <dir>` where `CACHEDIR.TAG` exists and is a regular file, but `open()` fails (e.g. EACCES, or a race where the file was removed between the `is_file()` check and the open).

Common situations: Permission issues on the target directory (read-only checkout, container with mismatched UID), filesystem race with another process, or a corrupted/inaccessible tag file.

Related errors


AI-assisted analysis of rust-lang/cargo@0e07a15537 (2026-08-06). Data as JSON: /data/errors/68e9219d2df02a72.json. Report an issue: GitHub.