nautechsystems/nautilus_trader · error

Failed to open file '{}' after {max_retries} attempts: {e}

Error message

Failed to open file '{}' after {max_retries} attempts: {e}

What it means

open_file_with_retry opens a file with up to max_retries attempts, sleeping between attempts. If every attempt fails (e.g. file missing, locked, or permission denied), it bails with this message including the path, attempt count, and the last underlying IO error.

Source

Thrown at crates/adapters/tardis/src/csv/mod.rs:88

fn create_csv_reader<P: AsRef<Path>>(
    filepath: P,
) -> anyhow::Result<Reader<Box<dyn std::io::Read>>> {
    const MAX_RETRIES: u8 = 3;
    const DELAY_MS: u64 = 100;
    const BUFFER_SIZE: usize = 8 * 1024 * 1024; // 8MB buffer for large files

    fn open_file_with_retry<P: AsRef<Path>>(
        path: P,
        max_retries: u8,
        delay_ms: u64,
    ) -> anyhow::Result<File> {
        let path_ref = path.as_ref();
        for attempt in 1..=max_retries {
            match File::open(path_ref) {
                Ok(file) => return Ok(file),
                Err(e) => {
                    if attempt == max_retries {
                        anyhow::bail!(
                            "Failed to open file '{}' after {max_retries} attempts: {e}",
                            path_ref.display()
                        );
                    }
                    log::warn!(
                        "Attempt {attempt}/{max_retries} failed to open file '{}': {e}. Retrying after {delay_ms}ms...",
                        path_ref.display()
                    );
                    std::thread::sleep(Duration::from_millis(delay_ms));
                }
            }
        }
        unreachable!("Loop should return either Ok or Err");
    }

    let filepath_ref = filepath.as_ref();
    let mut file = open_file_with_retry(filepath_ref, MAX_RETRIES, DELAY_MS)?;

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Verify the file path exists and is readable (check spelling, working directory, permissions)
  2. Check the underlying error {e} in the message: NotFound means fix the path; PermissionDenied means fix file ACLs
  3. Wait for the file to finish downloading/being written before processing
  4. Increase max_retries/delay if the storage is transiently unavailable
Defensive patterns

Strategy: retry

Validate before calling

use std::path::Path;
fn can_open(path: impl AsRef<Path>) -> bool {
    path.as_ref().is_file() && std::fs::metadata(&path)
        .map(|m| m.len() > 0).unwrap_or(false)
        // plus a probe: File::open(path).is_ok()
}

Try / catch

match create_csv_reader(path) {
    Ok(reader) => /* proceed */,
    Err(e) if e.to_string().contains("Failed to open file") => {
        log::error!("file unavailable: {e:#}");
        // fix path/permissions or wait and retry
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling create_csv_reader on a path that cannot be opened after all retry attempts — nonexistent path, permission denied, file locked by another process, or transient network-filesystem failure.

Common situations: Wrong path in dataset configuration; file not yet fully downloaded/uploaded; Windows file locking by another reader; NFS/S3-mounted files with transient unavailability.

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 nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/ffe12bd45611b533. Report an issue: GitHub.