rust-lang/rust · error

failed to create {dst:?}: {e}

Error message

failed to create {dst:?}: {e}

What it means

Panics inside copy_dir_recursively when fs::create_dir fails to create a destination directory while recursively copying a tree. cg_clif's build system uses this to stage the rustc source/library into a target directory (see prepare.rs:245,247). The panic is unrecoverable because the subsequent file copies depend on the directory existing.

Source

Thrown at compiler/rustc_codegen_cranelift/build_system/utils.rs:219

                Ok(()) => {}
                Err(err) if err.kind() == io::ErrorKind::NotFound => {}
                Err(err) => panic!("Failed to remove {path}: {err}", path = entry.path().display()),
            }
        }
    }
}

pub(crate) fn copy_dir_recursively(from: &Path, to: &Path) {
    for entry in fs::read_dir(from).unwrap() {
        let entry = entry.unwrap();
        let filename = entry.file_name();
        if filename == "." || filename == ".." {
            continue;
        }
        let src = from.join(&filename);
        let dst = to.join(&filename);
        if entry.metadata().unwrap().is_dir() {
            fs::create_dir(&dst).unwrap_or_else(|e| panic!("failed to create {dst:?}: {e}"));
            copy_dir_recursively(&src, &dst);
        } else {
            fs::copy(&src, &dst).unwrap_or_else(|e| panic!("failed to copy {src:?}->{dst:?}: {e}"));
        }
    }
}

static IN_GROUP: AtomicBool = AtomicBool::new(false);
pub(crate) struct LogGroup {
    is_gha: bool,
}

impl LogGroup {
    pub(crate) fn guard(name: &str) -> LogGroup {
        let is_gha = env::var("GITHUB_ACTIONS").is_ok();

        assert!(!IN_GROUP.swap(true, Ordering::SeqCst));
        if is_gha {

View on GitHub (pinned to 22057b88b0)

Solutions

  1. Confirm the destination root exists and is writable: `ls -ld <parent of dst>` and `touch <parent>/.write-probe`.
  2. Remove a stale conflicting file/symlink at the dst path and re-run `./y.rs prepare`.
  3. Free disk space on the target volume and re-run.
  4. If reproducing in CI, ensure the working dir is cleaned between runs (the prepare step assumes an empty/overwritable target).

Example fix

// before
fs::create_dir(&dst).unwrap_or_else(|e| panic!("failed to create {dst:?}: {e}"));
// after
if let Err(e) = fs::create_dir(&dst) {
    if e.kind() != io::ErrorKind::AlreadyExists {
        panic!("failed to create {dst:?}: {e}");
    }
}
Defensive patterns

Strategy: validation

Validate before calling

use std::path::Path;
fn ensure_creatable(dst: &Path) -> Result<(), String> {
    if dst.exists() {
        return Ok(());
    }
    let parent = dst.parent().ok_or_else(|| format!("dst {:?} has no parent", dst))?;
    if !parent.exists() {
        return Err(format!("parent dir {:?} does not exist; create it first", parent));
    }
    let md = std::fs::metadata(parent).map_err(|e| format!("cannot stat parent {:?}: {}", parent, e))?;
    if md.permissions().readonly() {
        return Err(format!("parent of {:?} is on a readonly filesystem", dst));
    }
    if let Ok(s) = std::fs::statvfs(parent) {
        if s.available_space() < 1024 {
            return Err(format!("no free space on volume holding {:?}", dst));
        }
    }
    Ok(())
}

Try / catch

use std::panic;
let res = panic::catch_unwind(|| fs::create_dir(dst));
if res.is_err() { /* log, clean partial dst, propagate as io::Error */ }

Prevention

When it happens

Trigger: Invoked during `./y.rs prepare` (or the rustbuild bootstrap path) when copy_dir_recursively encounters a subdirectory entry whose destination path cannot be created. The error string interpolates the failing dst path and the underlying io::Error.

Common situations: Destination lives on a read-only mount or under a path the user lacks write permission for; the parent of dst was removed by a concurrent process; dst already exists as a non-directory file (e.g. a stray symlink or text file shadows a dir name); ENOSPC on the target volume; path-length limits on Windows.

Related errors


AI-assisted analysis of rust-lang/rust@22057b88b0 (2026-08-03). Data as JSON: /data/errors/83946361b2230831.json. Report an issue: GitHub.