aio-libs/aiohttp · error · RuntimeError

Resolver requires aiodns library

Error message

Resolver requires aiodns library

What it means

Raised by AsyncResolver.__init__ when the aiodns package is not importable. aiohttp resolvers are pluggable; AsyncResolver delegates to aiodns for true non-blocking DNS. If aiodns is missing, construction aborts with RuntimeError so the failure is loud rather than silently falling back to the threaded resolver. Install aiodns or use the default ThreadedResolver.

Source

Thrown at aiohttp/resolver.py:107

                    port=port,
                    family=family,
                    proto=proto,
                    flags=_NUMERIC_SOCKET_FLAGS,
                )
            )

        return hosts

    async def close(self) -> None:
        pass


class AsyncResolver(AbstractResolver):
    """Use the `aiodns` package to make asynchronous DNS lookups"""

    def __init__(self, *args: Any, **kwargs: Any) -> None:
        if aiodns is None:
            raise RuntimeError("Resolver requires aiodns library")

        self._loop = asyncio.get_running_loop()
        self._manager: _DNSResolverManager | None = None
        # If custom args are provided, create a dedicated resolver instance
        # This means each AsyncResolver with custom args gets its own
        # aiodns.DNSResolver instance
        if args or kwargs:
            self._resolver = aiodns.DNSResolver(*args, **kwargs)
            return
        # Use the shared resolver from the manager for default arguments
        self._manager = _DNSResolverManager()
        self._resolver = self._manager.get_resolver(self, self._loop)

    async def resolve(
        self, host: str, port: int = 0, family: socket.AddressFamily = socket.AF_INET
    ) -> list[ResolveResult]:
        try:
            try:

View on GitHub (pinned to c0ef574e29)

Solutions

  1. Install aiodns: `pip install aiodns` (on Alpine also `apk add libcares`/build deps for cffi).
  2. If you do not need async DNS, do not pass AsyncResolver — rely on the default (ThreadedResolver when aiodns is absent).
  3. Pin aiodns>=3.0 for modern Python versions and ensure wheels exist for your platform.
  4. Verify with `python -c 'import aiodns'` after install.

Example fix

// before
from aiohttp.resolver import AsyncResolver
connector = TCPConnector(resolver=AsyncResolver())
// after
# Option A: install dependency
#   pip install aiodns
# Option B: use default resolver
connector = TCPConnector()  # ThreadedResolver by default
Defensive patterns

Strategy: validation

Validate before calling

try:
    import aiodns  # noqa
    HAS_AIODNS = True
except ImportError:
    HAS_AIODNS = False

from aiohttp.resolver import AsyncResolver, ThreadedResolver

resolver = AsyncResolver() if HAS_AIODNS else ThreadedResolver()

Try / catch

try:
    resolver = AsyncResolver()
except RuntimeError:
    # aiodns missing — fall back
    resolver = ThreadedResolver()

Prevention

When it happens

Trigger: Instantiating aiohttp.resolver.AsyncResolver() (explicitly, or via connector=TCPConnector(resolver=AsyncResolver())) without aiodns installed. Also triggered if aiodns is installed but its import fails due to a broken cffi/pycares build.

Common situations: Deploying to a slim container or Alpine image that omits aiodns; pinning requirements without aiodns; upgrading Python in a way that breaks aiodns' cffi wheels; using AsyncResolver as DefaultResolver when aiodns was optional.

Related errors


AI-assisted analysis of aio-libs/aiohttp@c0ef574e29 (2026-08-04). Data as JSON: /data/errors/c81193fbab12af47.json. Report an issue: GitHub.