{"record":{"id":"1c7e804704b80ce8","repo":"microsoft/FASTER","slug":"error-reading-from-log-file","errorCode":null,"errorMessage":"Error reading from log file","messagePattern":"Error reading from log file","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"cs/src/core/Device/LocalStorageDevice.cs","lineNumber":243,"sourceCode":"\n            try\n            {\n                var logHandle = GetOrAddHandle(segmentId);\n\n                Interlocked.Increment(ref numPending);\n\n                bool _result = Native32.ReadFile(logHandle,\n                                                destinationAddress,\n                                                readLength,\n                                                out uint bytesRead,\n                                                ovNative);\n\n                if (!_result)\n                {\n                    int error = Marshal.GetLastWin32Error();\n                    if (error != Native32.ERROR_IO_PENDING)\n                    {\n                        throw new IOException(\"Error reading from log file\", error);\n                    }\n                }\n            }\n            catch (IOException e)\n            {\n                Interlocked.Decrement(ref numPending);\n                callback((uint)(e.HResult & 0x0000FFFF), 0, context);\n                results.Enqueue(result);\n            }\n            catch\n             {\n                Interlocked.Decrement(ref numPending);\n                callback(uint.MaxValue, 0, context);\n                results.Enqueue(result);\n            }\n        }\n\n        /// <summary>","sourceCodeStart":225,"sourceCodeEnd":261,"githubUrl":"https://github.com/microsoft/FASTER/blob/321d872eabda6a0345c8bd76419f89723ed864ae/cs/src/core/Device/LocalStorageDevice.cs#L225-L261","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Inspect the wrapped Win32 error (IOException.HResult / error code) to identify the root cause (e.g., ERROR_HANDLE_EOF, ERROR_SECTOR misalignment).","Verify the segment file exists and the device has not been disposed before issuing reads.","Ensure read addresses/length are aligned to sector size and within the segment's length.","Recover by re-creating the device from a valid checkpoint if the underlying file is corrupt."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"if (device.IsDisposed) throw new ObjectDisposedException(nameof(device));\nDebug.Assert(address % sectorSize == 0);","typeGuard":null,"tryCatchPattern":"try { await device.ReadAsync(...); } catch (IOException e) { int win32 = Marshal.GetHRForLastWin32Error(); log.LogError(e, \"Segment read failed, win32={Win32}\", win32); }","preventionTips":["Never dispose the device while reads are in flight; use the epoch system for shutdown.","Validate addresses are within a live segment before reading.","Monitor disk health and free space on the log volume."],"tags":["io","windows","file-read","storage-device"],"backgroundTag":"file-read-failed","analyzedSha":"321d872eabda6a0345c8bd76419f89723ed864ae","analyzedAt":"2026-09-15T22:18:00.693Z","contentChangedAt":"2026-09-15T22:18:00.693Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}