seanmonstar/warp · error · FileOpenError
file_open_error
Error message
file_open_error
What it means
FileOpenError is the rejection returned by warp::fs::file / file_reply (src/filters/fs.rs) when std::fs::File::open on the requested path fails. The path was resolved but could not be opened, most commonly because it does not exist or the process lacks read permission. The error is logged (the underlying io::Error is printed) and a generic file_open_error rejection is returned so internals are not leaked.
Solutions
- Verify the file exists at the exact path (use an absolute path in warp::fs::file)
- Check the file's permissions and the user the server process runs as
- Confirm relative paths resolve from the process working directory, not the crate root
- If serving a directory, use warp::fs::dir instead of fs::file
- Check the server log next to this rejection: the real io::Error is printed there
Example fix
// before
let route = warp::path("report").and(warp::fs::file("out/report.pdf"));
// after
let route = warp::path("report")
.and(warp::fs::file("/var/www/assets/report.pdf")); Defensive patterns
Strategy: validation
Validate before calling
// check before serving
let path = std::path::Path::new("/var/www/assets/report.pdf");
if !path.is_file() {
eprintln!("missing or not a file: {}", path.display());
}
match std::fs::File::open(path) {
Ok(_) => (),
Err(e) => eprintln!("cannot open {}: {}", path.display(), e),
} Type guard
fn is_readable_file(p: &str) -> bool {
std::fs::File::open(p).is_ok()
} Try / catch
let route = warp::path("report")
.and(warp::fs::file("/var/www/assets/report.pdf"))
.recover(|rej: warp::Rejection| async move {
if rej.find::<warp::reject::FileOpenError>().is_some() {
Ok(warp::reply::with_status("file unavailable", warp::http::StatusCode::NOT_FOUND))
} else {
Err(rej)
}
}); Prevention
- Use absolute paths for static assets
- Verify the file exists in your deploy/CI step before the server starts
- Mount volumes correctly in containers and check read permissions for the runtime user
- Prefer warp::fs::dir for directory-based serving
- Log the working directory at startup if using relative paths
When it happens
Trigger: warp::fs::file("path") or fs::file_reply used with a path that does not exist, is a directory opened as a file, has a broken symlink, or is unreadable by the server process (permission denied).
Common situations: Relative path resolved against an unexpected working directory; serving static assets where the build output folder wasn't deployed; file deleted between route match and open; Docker container missing the mounted file; running the server as a user without read access to the asset directory.
Understand the failure class
Background: "open() failed", "failed to open file", "cannot create file" — what a file open error means and how to fix it — this error's family across 42 libraries.
Related errors
AI-assisted analysis of seanmonstar/warp@ff34d7213e (2026-09-09).
Data as JSON: /api/errors/6fe4e3202b613176.
Report an issue: GitHub.
Appendix: source
Thrown at src/filters/fs.rs:289
let rej = match err.kind() {
io::ErrorKind::NotFound => {
tracing::debug!("file not found: {:?}", path.as_ref().display());
reject::not_found()
}
io::ErrorKind::PermissionDenied => {
tracing::warn!("file permission denied: {:?}", path.as_ref().display());
reject::known(FilePermissionError { _p: () })
}
_ => {
tracing::error!(
"file open error (path={:?}): {} ",
path.as_ref().display(),
err
);
reject::known(FileOpenError { _p: () })
}
};
Either::Right(future::err(rej))
}
})
}
async fn file_metadata(f: TkFile) -> Result<(TkFile, Metadata), Rejection> {
match f.metadata().await {
Ok(meta) => Ok((f, meta)),
Err(err) => {
tracing::debug!("file metadata error: {}", err);
Err(reject::not_found())
}
}
}
fn file_conditional(
f: TkFile,
path: ArcPath,
conditionals: Conditionals,View on GitHub (pinned to ff34d7213e)