rust-lang/rust · error · io::Error

Path already exists

Error message

Path already exists

What it means

The UEFI mkdir implementation checks for an existing path by trying to open it first; if the open succeeds the target already exists, so it returns Err(io::ErrorKind::AlreadyExists) (uefi.rs:870-877). This mirrors POSIX EEXIST semantics for create_dir on the UEFI backend.

Source

Thrown at library/std/src/sys/fs/uefi.rs:873

                    return helpers::os_string_to_raw(&p);
                }
                _ => return None,
            }
        }
    }

    /// An implementation of mkdir to allow creating new directory without having to open the
    /// volume twice (once for checking and once for creating)
    pub(crate) fn mkdir(path: &Path) -> io::Result<()> {
        let absolute = crate::path::absolute(path)?;

        let p = helpers::OwnedDevicePath::from_text(absolute.as_os_str())?;
        let (vol, mut path_remaining) = File::open_volume_from_device_path(p.borrow())?;

        // Check if file exists
        match File::open(vol, &mut path_remaining, file::MODE_READ, 0) {
            Ok(_) => {
                return Err(io::Error::new(io::ErrorKind::AlreadyExists, "Path already exists"));
            }
            Err(e) if e.kind() == io::ErrorKind::NotFound => {}
            Err(e) => return Err(e),
        }

        let _ = File::open(
            vol,
            &mut path_remaining,
            file::MODE_READ | file::MODE_WRITE | file::MODE_CREATE,
            file::DIRECTORY,
        )?;

        Ok(())
    }

    /// EDK2 FAT driver uses EFI_UNSPECIFIED_TIMEZONE to represent localtime. So for proper
    /// conversion to SystemTime, we use the current time to get the timezone in such cases.
    pub(crate) fn uefi_to_systemtime(mut time: r_efi::efi::Time) -> Option<SystemTime> {

View on GitHub (pinned to 7088e4b63a)

Solutions

  1. Use fs::create_dir_all(p), which treats an existing directory as success.
  2. Match on io::ErrorKind::AlreadyExists and treat it as non-fatal when appropriate.
  3. Check fs::exists(p) / metadata before calling create_dir if you need to branch.

Example fix

// before
std::fs::create_dir("/data/cache")?;
// after
std::fs::create_dir_all("/data/cache")?;
Defensive patterns

Strategy: try-catch

Validate before calling

// Best-effort existence check (note TOCTOU; prefer matching the error).
if std::fs::exists(p)? {
    // already present, skip creation
}

Try / catch

match std::fs::create_dir(p) {
    Ok(()) => Ok(()),
    Err(e) if e.kind() == std::io::ErrorKind::AlreadyExists => Ok(()),
    Err(e) => Err(e),
}

Prevention

When it happens

Trigger: Calling fs::create_dir(p) on UEFI when p (file or directory) already exists; create_dir_all reaching an existing leaf.

Common situations: Re-running setup/init code that creates a directory; a concurrent writer creating the same path; boot-time directory provisioning.

Related errors


AI-assisted analysis of rust-lang/rust@7088e4b63a (2026-08-10). Data as JSON: /api/errors/889cecc64b847513. Report an issue: GitHub.