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
- On Windows, ensure the proactor loop is active: `asyncio.set_event_loop_policy(asyncio.WindowsProactorEventLoopPolicy())` at startup.
- On Unix, use UnixSite (UDS) instead of NamedPipeSite.
- Gate the import/construction by platform: `if os.name == 'nt': NamedPipeSite(...) else: UnixSite(...)`.
- 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
- On Windows, set WindowsProactorEventLoopPolicy at startup before named-pipe use.
- On Unix, use UnixSite instead of NamedPipeSite.
- Gate NamedPipeSite construction by platform check.
- Do not override the loop policy to a selector policy if you need pipes.
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
- Named Pipes only available in proactor loop under windows
- Call runner.setup() before making a site
- Site is already registered in runner
- Site is not registered in runner
- body and text are not allowed together
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)