actix/actix-web · warning · io::Error
No such file
Error message
No such file
What it means
An io::Error of kind NotFound with message "No such file" is the fallback used by the Files service (service.rs:290) when directory traversal completes without ever recording a NotFound/NotADirectory miss. It is passed to handle_err, which by default produces a 404 response. In practice most 404s come from the stored last_miss IO error; this string is the edge-case default when no open was even attempted.
Solutions
- Verify the directory configured in Files::new(...) exists and is readable by the server process.
- Set an index file via .index_file("index.html") and/or enable .show_files(true) for listing.
- Register a custom default handler (App::default_service) to render a friendly 404 page.
Example fix
// before
App::new().service(Files::new("/assets", "/nonexistent/dir"))
// after
App::new().service(
Files::new("/assets", "/srv/site/assets")
.index_file("index.html")
) Defensive patterns
Strategy: fallback
Validate before calling
// Confirm the served directory exists at startup
let root = Path::new(SERVE_DIR);
assert!(root.is_dir(), "static dir missing: {SERVE_DIR}"); Try / catch
// Provide a friendly 404 fallback
App::new()
.service(Files::new("/assets", SERVE_DIR).index_file("index.html"))
.default_service(web::to(|| HttpResponse::NotFound().body("not found"))) Prevention
- Verify the served directory exists and is readable at startup.
- Set an index file or enable show_files as appropriate.
- Deploy static assets as part of your build/pipeline.
When it happens
Trigger: A request maps to a directory that exists but contains no index file, directory listing is disabled, and no candidate file open produced a NotFound error - e.g. an empty resolved path or a config where index/show_index are both off and the target is an unrenderable directory branch.
Common situations: Misconfigured Files::new root pointing at a missing directory; index file not set and listing disabled; deploy where static assets were not copied into the served directory.
Related errors
- Provided path has no filename
- actix-http client only supports versions http/1.1 & http/2
- Could not parse size limit
- invalid Range header: invalid syntax
- invalid Range header: range starts after end of content
AI-assisted analysis of actix/actix-web@7ae209e4a4 (2026-08-09).
Data as JSON: /api/errors/86bbefaff1a0b57b.
Report an issue: GitHub.
Appendix: source
Thrown at actix-files/src/service.rs:290
}
Err(err) => return this.handle_err(err, req).await,
}
}
}
if let Some((base, path)) = first_index_listing {
return Ok(this.show_index(req, base, path));
}
if found_unrenderable_dir {
return Ok(ServiceResponse::from_err(
FilesError::IsDirectory,
req.into_parts().0,
));
}
let err = last_miss
.unwrap_or_else(|| io::Error::new(io::ErrorKind::NotFound, "No such file"));
this.handle_err(err, req).await
})
}
}
/// Flate doesn't have an accepted file extension, so it is not included here.
const SUPPORTED_PRECOMPRESSION_ENCODINGS: &[header::ContentEncoding] = &[
header::ContentEncoding::Brotli,
header::ContentEncoding::Gzip,
header::ContentEncoding::Zstd,
header::ContentEncoding::Identity,
];
/// Searches disk for an acceptable alternate encoding of the content at the given path, as
/// preferred by the request's `Accept-Encoding` header. Returns the corresponding `NamedFile` with
/// the most appropriate supported encoding, if any exist.
async fn find_compressed(
req: &ServiceRequest,View on GitHub (pinned to 7ae209e4a4)