microsoft/aspire · error · OSError

ReadFile failed with error

Error message

ReadFile failed with error {error}

What it means

Raised by the Windows named-pipe socket wrapper when the ReadFile Win32 call fails with an error other than the expected pending/overlap states during overlapped I/O. It wraps the raw Win32 error code, meaning the pipe read itself failed (pipe broken, disconnected, or handle invalid).

Solutions

  1. Catch OSError in the receive path and reconnect to the pipe (re-run connect logic).
  2. Check whether the host process is still alive; restart it if it crashed.
  3. Log the Win32 error code (231=ERROR_BROKEN_PIPE is most common) to distinguish disconnect from code bugs.
  4. Avoid sharing a single _PipeSocket across threads without synchronization; concurrent reads can corrupt overlapped I/O state.

Example fix

// before
data = socket.recv(4096)

// after
try:
    data = socket.recv(4096)
except OSError:
    socket = reconnect_to_pipe(pipe_path, timeout_sec=30)
Defensive patterns

Strategy: try-catch

Try / catch

try:
    data = sock.recv(n)
except OSError:
    sock = reconnect_to_pipe(pipe_path, timeout_sec=30)
    data = sock.recv(n)

Prevention

When it happens

Trigger: Reading from a pipe whose host end has closed (ERROR_BROKEN_PIPE), or after the handle was invalidated/closed, or an overlapped-operation failure not converted to a pending state.

Common situations: Host process exited mid-session; abrupt termination of the AppHost while the client waits for a response; network-less local pipe torn down on host restart.

Related errors


AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16). Data as JSON: /api/errors/23a0474bf0908367. Report an issue: GitHub.

Appendix: source

Thrown at src/Aspire.Hosting.CodeGeneration.Python/PythonModuleBuilder.cs:366

                            self._handle,
                            buffer,
                            n,
                            ctypes.byref(bytes_read),
                            ctypes.byref(overlapped)
                        )

                        if not success:
                            error = ctypes.get_last_error()
                            if error == self.ERROR_IO_PENDING:
                                # Wait for the operation to complete
                                _kernel32.GetOverlappedResult(
                                    self._handle,
                                    ctypes.byref(overlapped),
                                    ctypes.byref(bytes_read),
                                    True  # wait
                                )
                            else:
                                raise OSError(f"ReadFile failed with error {error}")
                    finally:
                        _kernel32.CloseHandle(overlapped.hEvent)

                    return buffer.raw[:bytes_read.value]

                def sendall(self, data: bytes) -> None:
                    '''Write all data using overlapped I/O.'''
                    bytes_written = wintypes.DWORD()
                    overlapped = self._create_overlapped_event()

                    try:
                        offset = 0
                        while offset < len(data):
                            chunk = data[offset:]

                            success = _kernel32.WriteFile(
                                self._handle,
                                chunk,

View on GitHub (pinned to 25830f84bd)