microsoft/FASTER · error · IOException

Error reading from log file

Error message

Error reading from log file

What it means

ReadAsync issues an overlapped Win32 read on the segment file. If the native call returns false and the last Win32 error is not ERROR_IO_PENDING (i.e., the read failed outright, not just asynchronously pending), an IOException wrapping the Win32 error code is thrown.

Solutions

  1. Inspect the wrapped Win32 error (IOException.HResult / error code) to identify the root cause (e.g., ERROR_HANDLE_EOF, ERROR_SECTOR misalignment).
  2. Verify the segment file exists and the device has not been disposed before issuing reads.
  3. Ensure read addresses/length are aligned to sector size and within the segment's length.
  4. Recover by re-creating the device from a valid checkpoint if the underlying file is corrupt.
Defensive patterns

Strategy: try-catch

Validate before calling

if (device.IsDisposed) throw new ObjectDisposedException(nameof(device));
Debug.Assert(address % sectorSize == 0);

Try / catch

try { await device.ReadAsync(...); } catch (IOException e) { int win32 = Marshal.GetHRForLastWin32Error(); log.LogError(e, "Segment read failed, win32={Win32}", win32); }

Prevention

When it happens

Trigger: Calling ReadAsync when the underlying segment file handle is invalid/closed, the requested offset is beyond the file (or volume), disk I/O fails, or the device is disposed mid-read.

Common situations: Reading a segment that was deleted or corrupted; disk full/hardware errors; sector misalignment; concurrent dispose of the device while reads are in flight; passing addresses whose segment file no longer exists.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


AI-assisted analysis of microsoft/FASTER@321d872eab (2026-09-15). Data as JSON: /api/errors/1c7e804704b80ce8. Report an issue: GitHub.

Appendix: source

Thrown at cs/src/core/Device/LocalStorageDevice.cs:243

            try
            {
                var logHandle = GetOrAddHandle(segmentId);

                Interlocked.Increment(ref numPending);

                bool _result = Native32.ReadFile(logHandle,
                                                destinationAddress,
                                                readLength,
                                                out uint bytesRead,
                                                ovNative);

                if (!_result)
                {
                    int error = Marshal.GetLastWin32Error();
                    if (error != Native32.ERROR_IO_PENDING)
                    {
                        throw new IOException("Error reading from log file", error);
                    }
                }
            }
            catch (IOException e)
            {
                Interlocked.Decrement(ref numPending);
                callback((uint)(e.HResult & 0x0000FFFF), 0, context);
                results.Enqueue(result);
            }
            catch
             {
                Interlocked.Decrement(ref numPending);
                callback(uint.MaxValue, 0, context);
                results.Enqueue(result);
            }
        }

        /// <summary>

View on GitHub (pinned to 321d872eab)