Skip to content

ReadDir on Windows can return error infinitely when run on removable path #142411

@vthib

Description

@vthib

The std::fs::ReadDir iterator, returned by a call to std::fs::read_dir, can return an error forever in some cases on Windows. Notably, this can happen when reading a directory that is on a removable device (such as an usb drive), and removing this device:

fn main() {
    for entry in std::fs::read_dir("E:").unwrap() {
        println!("entry: {:?}", entry);
        std::thread::sleep(std::time::Duration::from_millis(500));
    }
}

With this scenario:

  • Mount an USB drive that contains a hundred file onto E:
  • Run the test
  • While the test is running, unplug the drive

This test gives something like this:

entry: Ok(DirEntry("E:file1"))
entry: Ok(DirEntry("E:file2"))
entry: Ok(DirEntry("E:file3"))
entry: Ok(DirEntry("E:file4"))
entry: Ok(DirEntry("E:file5"))
entry: Err(Os { code: 21, kind: Uncategorized, message: "The device is not ready." })
entry: Err(Os { code: 21, kind: Uncategorized, message: "The device is not ready." })
entry: Err(Os { code: 21, kind: Uncategorized, message: "The device is not ready." })
entry: Err(Os { code: 21, kind: Uncategorized, message: "The device is not ready." })
entry: Err(Os { code: 21, kind: Uncategorized, message: "The device is not ready." })
entry: Err(Os { code: 21, kind: Uncategorized, message: "The device is not ready." })
entry: Err(Os { code: 21, kind: Uncategorized, message: "The device is not ready." })
entry: Err(Os { code: 21, kind: Uncategorized, message: "The device is not ready." })
entry: Err(Os { code: 21, kind: Uncategorized, message: "The device is not ready." })
...

I have also observed the error ERROR_WRONG_DISK (code 34) and the error ERROR_FILE_INVALID (code 1006) under this scenario.

This feels a bit similar to #50619 which was for a similar issue (infinite loop on the iterator) but on Linux.

ReadDir is documented as follows:

This io::Result will be an Err if there’s some sort of intermittent IO error during iteration.

However this error is not intermittent: replugging the usb drive will not make the iteration start returning OK values.

I'm not sure how easy this issue is to fix however. Maybe detecting the error code to distinguish intermittent errors from non intermittent ones, but just this simple test can return at least 3 different error codes in my tests, so that seems hard do properly.

Meta

rustc --version --verbose:

rustc 1.87.0 (17067e9ac 2025-05-09)
binary: rustc
commit-hash: 17067e9ac6d7ecb70e50f92c1944e545188d2359
commit-date: 2025-05-09
host: x86_64-pc-windows-msvc
release: 1.87.0
LLVM version: 20.1.1

Also tested on nightly, same results:

rustc 1.89.0-nightly (e703dff8f 2025-06-11)
binary: rustc
commit-hash: e703dff8fe220b78195c53478e83fb2f68d8499c
commit-date: 2025-06-11
host: x86_64-pc-windows-msvc
release: 1.89.0-nightly
LLVM version: 20.1.5

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: This is a bug.O-windowsOperating system: Windowsneeds-triageThis issue may need triage. Remove it if it has been sufficiently triaged.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions