aio-libs/aiohttp · error · RuntimeError

Named Pipes only available in proactor loop under windows

Error message

Named Pipes only available in proactor loop under windows

What it means

Raised by NamedPipeSite.__init__ when the running asyncio loop is not a ProactorEventLoop. Windows named pipes rely on the proactor loop's overlapped I/O subsystem; selector loops (the default on Unix, and the UnixSelectorEventLoop on Wine/WSL) cannot service pipe handles, so aiohttp refuses to construct the site.

Solutions

  1. On Windows, ensure the proactor loop is active: `asyncio.set_event_loop_policy(asyncio.WindowsProactorEventLoopPolicy())` at startup.
  2. On Unix, use UnixSite (UDS) instead of NamedPipeSite.
  3. Gate the import/construction by platform: `if os.name == 'nt': NamedPipeSite(...) else: UnixSite(...)`.
  4. Avoid overriding the loop policy to a selector policy when you intend to use named pipes.

Example fix

// before (on Linux)
site = NamedPipeSite(runner, r'\\.\pipe\foo')  # RuntimeError

// after (on Linux)
site = UnixSite(runner, '/run/app.sock')

// or on Windows, force proactor loop
import asyncio, sys
if sys.platform == 'win32':
    asyncio.set_event_loop_policy(asyncio.WindowsProactorEventLoopPolicy())
site = NamedPipeSite(runner, r'\\.\pipe\foo')
Defensive patterns

Strategy: validation

Validate before calling

import sys, asyncio

def make_named_pipe_site(runner, path):
    loop = asyncio.get_event_loop()
    if sys.platform != 'win32' or not isinstance(loop, asyncio.ProactorEventLoop):
        raise RuntimeError('NamedPipeSite requires Windows ProactorEventLoop')
    return NamedPipeSite(runner, path)

Type guard

import sys, asyncio

def supports_named_pipe() -> bool:
    if sys.platform != 'win32':
        return False
    loop = asyncio.get_event_loop()
    return isinstance(loop, asyncio.ProactorEventLoop)

Prevention

When it happens

Trigger: Constructing `NamedPipeSite(runner, path)` on Linux/macOS, or on Windows under a non-proactor loop (e.g. explicitly set via `asyncio.set_event_loop_policy(asyncio.UnixSelectorEventLoopPolicy())`, or under uvloop which has no proactor).

Common situations: Cross-platform code that unconditionally uses NamedPipeSite; running on Unix where named pipes should use UnixSite instead; running under uvloop on Windows (uvloop doesn't exist there but the policy may still mis-set the loop type); containerized deployments on Linux that share code with a Windows service.

Related errors


AI-assisted analysis of aio-libs/aiohttp@d041d4d0fd (2026-08-11). Data as JSON: /api/errors/2aabca94cd51936b. Report an issue: GitHub.

Appendix: source

Thrown at aiohttp/web_runner.py:238

        server = self._runner.server
        assert server is not None
        self._server = await loop.create_unix_server(
            server,
            self._path,
            ssl=self._ssl_context,
            backlog=self._backlog,
        )


class NamedPipeSite(BaseSite):
    __slots__ = ("_path",)

    def __init__(self, runner: "BaseRunner[Any]", path: str) -> None:
        loop = asyncio.get_running_loop()
        if not isinstance(
            loop, asyncio.ProactorEventLoop  # type: ignore[attr-defined]
        ):
            raise RuntimeError(
                "Named Pipes only available in proactor loop under windows"
            )
        super().__init__(runner)
        self._path = path

    @property
    def name(self) -> str:
        return self._path

    async def start(self) -> None:
        await super().start()
        loop = asyncio.get_running_loop()
        server = self._runner.server
        assert server is not None
        _server = await loop.start_serving_pipe(  # type: ignore[attr-defined]
            server, self._path
        )
        self._server = _server[0]

View on GitHub (pinned to d041d4d0fd)