uutils/coreutils · error · io::Error

could not allocate a unique temp name in destination directo

Error message

could not allocate a unique temp name in destination directory

What it means

For atomic symlink replacement, create_symlink_replace first creates a uniquely-named temporary symlink inside the destination directory (to then rename it over the target). If, after repeated attempts, no unique temp name can be allocated, it gives up with this AlreadyExists error rather than risk clobbering anything.

Source

Thrown at src/uu/mv/src/mv.rs:1107

        urandom.read_exact(&mut raw)?;
        for (slot, byte) in tmp_bytes[2..].iter_mut().zip(raw) {
            *slot = ALPHABET[(byte as usize) % ALPHABET.len()];
        }
        let tmp = OsStr::from_bytes(&tmp_bytes);

        match symlinkat(target, &dir_fd, tmp) {
            Ok(()) => {
                if let Err(e) = renameat(&dir_fd, tmp, &dir_fd, basename) {
                    let _ = unlinkat(&dir_fd, tmp, AtFlags::empty());
                    return Err(io::Error::from(e));
                }
                return Ok(());
            }
            Err(e) if e == rustix::io::Errno::EXIST => {}
            Err(e) => return Err(io::Error::from(e)),
        }
    }
    Err(io::Error::new(
        io::ErrorKind::AlreadyExists,
        "could not allocate a unique temp name in destination directory",
    ))
}

#[cfg(windows)]
fn rename_symlink_fallback(from: &Path, to: &Path) -> io::Result<()> {
    let path_symlink_points_to = fs::read_link(from)?;
    if path_symlink_points_to.exists() {
        if path_symlink_points_to.is_dir() {
            windows::fs::symlink_dir(&path_symlink_points_to, to)?;
        } else {
            windows::fs::symlink_file(&path_symlink_points_to, to)?;
        }
        fs::remove_file(from)
    } else {
        Err(io::Error::new(
            io::ErrorKind::NotFound,

View on GitHub (pinned to 85295bbf78)

Solutions

  1. Retry the mv — temp-name allocation is randomized, so a one-off failure is transient
  2. Check destination directory permissions and that the filesystem supports creating symlinks (Windows may require privileges) with `ln -s dest/.probe`
  3. Verify filesystem health (fsck / chkdsk) if it persists on that volume
  4. Fall back to a non-atomic replace (unlink then ln -s) if atomicity is not required, and report the bug

Example fix

null
Defensive patterns

Strategy: retry

Validate before calling

# ensure destination dir is writable and symlink creation works
touch "$dest_dir/.probe" && rm "$dest_dir/.probe" || { echo "dest not writable"; exit 1; }

Try / catch

// transient — retry the move a few times
for attempt in 1..=3 {
    match mv_symlink_replace(src, dst) {
        Ok(()) => break,
        Err(e) if e.kind() == io::ErrorKind::AlreadyExists && attempt < 3 => continue,
        Err(e) => return Err(e),
    }
}

Prevention

When it happens

Trigger: Creating a temp name (e.g., a randomized suffix via openat with O_EXCL semantics) fails with EEXIST on every attempt — astronomically unlikely by chance, but effectively certain if the directory listing is frozen (e.g., extremely hostile/high-entropy collision or a filesystem quirk always returning EXIST).

Common situations: Destination directory on an exotic filesystem that misreports EEXIST; a loop count exhausted due to a broken PRNG/tempname scheme; extremely constrained environments where the directory cannot be written but names always appear to exist.

Related errors


AI-assisted analysis of uutils/coreutils@85295bbf78 (2026-08-31). Data as JSON: /api/errors/50c779e8515189e1. Report an issue: GitHub.