{"record":{"id":"c81193fbab12af47","repo":"aio-libs/aiohttp","slug":"resolver-requires-aiodns-library","errorCode":null,"errorMessage":"Resolver requires aiodns library","messagePattern":"Resolver requires aiodns library","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"aiohttp/resolver.py","lineNumber":107,"sourceCode":"                    port=port,\n                    family=family,\n                    proto=proto,\n                    flags=_NUMERIC_SOCKET_FLAGS,\n                )\n            )\n\n        return hosts\n\n    async def close(self) -> None:\n        pass\n\n\nclass AsyncResolver(AbstractResolver):\n    \"\"\"Use the `aiodns` package to make asynchronous DNS lookups\"\"\"\n\n    def __init__(self, *args: Any, **kwargs: Any) -> None:\n        if aiodns is None:\n            raise RuntimeError(\"Resolver requires aiodns library\")\n\n        self._loop = asyncio.get_running_loop()\n        self._manager: _DNSResolverManager | None = None\n        # If custom args are provided, create a dedicated resolver instance\n        # This means each AsyncResolver with custom args gets its own\n        # aiodns.DNSResolver instance\n        if args or kwargs:\n            self._resolver = aiodns.DNSResolver(*args, **kwargs)\n            return\n        # Use the shared resolver from the manager for default arguments\n        self._manager = _DNSResolverManager()\n        self._resolver = self._manager.get_resolver(self, self._loop)\n\n    async def resolve(\n        self, host: str, port: int = 0, family: socket.AddressFamily = socket.AF_INET\n    ) -> list[ResolveResult]:\n        try:\n            try:","sourceCodeStart":89,"sourceCodeEnd":125,"githubUrl":"https://github.com/aio-libs/aiohttp/blob/d041d4d0fd48c3f0832084d33be16cf1c4835f85/aiohttp/resolver.py#L89-L125","documentation":"Raised by AsyncResolver.__init__ when the aiodns package is not importable (the module-level aiodns is None). AsyncResolver delegates DNS lookups to aiodns, so without it the resolver cannot function and fails fast at construction rather than silently falling back. This is a hard dependency for this resolver class only.","triggerScenarios":"Constructing aiohttp.AsyncResolver() (or passing connector=TCPConnector(resolver=AsyncResolver())) in an environment where aiodns is not installed or failed to import.","commonSituations":"Deploying to a fresh container/venv that installed aiohttp but not aiodns; CI matrix that omits the extras (pip install aiohttp without [speedups] or aiodns); aiodns import failing due to a broken pycares build.","solutions":["Install aiodns: pip install aiodns (or pip install 'aiohttp[speedups]').","Pin a working aiodns/pycares version if the import fails at runtime despite being installed.","If you cannot add aiodns, use the default ThreadedResolver (omit resolver=) which uses the stdlib socket module."],"exampleFix":"# before\nresolver = aiohttp.AsyncResolver()  # RuntimeError: requires aiodns\n\n# after (shell)\n# pip install aiodns\nresolver = aiohttp.AsyncResolver()","handlingStrategy":"validation","validationCode":"import importlib.util\nif importlib.util.find_spec('aiodns') is None:\n    resolver = None  # use default ThreadedResolver\nelse:\n    resolver = aiohttp.AsyncResolver()","typeGuard":"import importlib.util\ndef aiodns_available() -> bool:\n    return importlib.util.find_spec('aiodns') is not None","tryCatchPattern":"try:\n    resolver = aiohttp.AsyncResolver()\nexcept RuntimeError:\n    resolver = None  # fall back to default resolver","preventionTips":["Declare aiodns in your deployment requirements (pip install 'aiohttp[speedups]').","Pin aiodns + pycares versions known to build on your platform.","Make aiodns optional and fall back to ThreadedResolver when absent."],"tags":["dns","dependencies","resolver","environment"],"backgroundTag":null,"analyzedSha":"d041d4d0fd48c3f0832084d33be16cf1c4835f85","analyzedAt":"2026-08-11T20:44:15.550Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}