rust-lang/cargo · error · io::Error
the path was not found
Error message
the path was not found
What it means
`try_canonicalize` is a Windows-only helper (`#[cfg(windows)]`). `std::fs::canonicalize` on Windows can fail for various path forms, so the function falls back: first it re-checks existence with `try_exists()`; if the path does not exist it returns `io::Error::new(ErrorKind::NotFound, "the path was not found")`; otherwise it falls through to `std::path::absolute(&path)`. This preserves `canonicalize`'s behavior of erroring on non-existent paths while still returning an absolute path when canonicalization itself is the problem.
Solutions
- Verify the path exists (create the file/directory, or fix the typo) before canonicalizing.
- Check the working directory and that build artifacts have been generated prior to this call.
- For UNC/network paths, confirm the share is reachable and the path is correct.
Example fix
// before (Windows)
let p = try_canonicalize("C:\\build\\missing.exe")?; // NotFound
// after
std::fs::create_dir_all("C:\\build")?;
// ensure the file exists first, then canonicalize
let p = try_canonicalize("C:\\build\\real.exe")?; Defensive patterns
Strategy: validation
Validate before calling
use std::path::Path;
fn exists_before_canon(p: &Path) -> std::io::Result<bool> { p.try_exists() }
// on Windows, call this before try_canonicalize to surface a clear NotFound up front Try / catch
match try_canonicalize(path) {
Ok(p) => { /* use p */ }
Err(e) if e.kind() == std::io::ErrorKind::NotFound => {
// create the file/dir, or correct the path, then retry
}
Err(e) => return Err(e.into()),
} Prevention
- Ensure files/dirs exist before canonicalizing on Windows.
- Generate build artifacts before resolving their absolute paths.
- Validate working directory and share reachability for UNC paths.
When it happens
Trigger: Calling `try_canonicalize` on a Windows path where `std::fs::canonicalize` fails AND `path.as_ref().try_exists()?` returns `false` (the file genuinely does not exist). The explicit `NotFound` error is returned.
Common situations: Passing a non-existent path on Windows (typo, deleted file, not-yet-created build artifact, wrong working directory), or a path on a network/UNC location that cannot be resolved and does not exist.
Related errors
- ` ` was defined in but could not be resolved with
- can only edit absolute paths, got
- no executable for ` ` found in PATH
- non UTF8 path
- ` ` resolved to non-UTF value (` `)
AI-assisted analysis of rust-lang/cargo@98a09e7e7d (2026-08-11).
Data as JSON: /api/errors/f1413f5886f863c3.
Report an issue: GitHub.
Appendix: source
Thrown at src/util/mod.rs:160
}
#[cfg(not(windows))]
#[inline]
pub fn try_canonicalize<P: AsRef<Path>>(path: P) -> std::io::Result<PathBuf> {
std::fs::canonicalize(&path)
}
#[cfg(windows)]
#[inline]
pub fn try_canonicalize<P: AsRef<Path>>(path: P) -> std::io::Result<PathBuf> {
use std::io::Error;
use std::io::ErrorKind;
// On Windows `canonicalize` may fail, so we fall back to getting an absolute path.
std::fs::canonicalize(&path).or_else(|_| {
// Return an error if a file does not exist for better compatibility with `canonicalize`
if !path.as_ref().try_exists()? {
return Err(Error::new(ErrorKind::NotFound, "the path was not found"));
}
std::path::absolute(&path)
})
}
/// Get the current [`umask`] value.
///
/// [`umask`]: https://man7.org/linux/man-pages/man2/umask.2.html
#[cfg(unix)]
pub fn get_umask() -> u32 {
use std::sync::OnceLock;
static UMASK: OnceLock<libc::mode_t> = OnceLock::new();
// SAFETY: Syscalls are unsafe. Calling `umask` twice is even unsafer for
// multithreading program, since it doesn't provide a way to retrieve the
// value without modifications. We use a static `OnceLock` here to ensure
// it only gets call once during the entire program lifetime.
*UMASK.get_or_init(|| unsafe {
let umask = libc::umask(0o022);View on GitHub (pinned to 98a09e7e7d)