{"record":{"id":"451f802143a10836","repo":"scrapy/scrapy","slug":"type-self-name-requires-the-asyncio-support","errorCode":null,"errorMessage":"{type(self).__name__} requires the asyncio support. Make sure that you have either enabled the asyncio Twisted reactor in the TWISTED_REACTOR setting or disabled the TWISTED_REACTOR_ENABLED setting. See the asyncio documentation of Scrapy for more information.","messagePattern":"(.+?) requires the asyncio support\\. Make sure that you have either enabled the asyncio Twisted reactor in the TWISTED_REACTOR setting or disabled the TWISTED_REACTOR_ENABLED setting\\. See the asyncio documentation of Scrapy for more information\\.","errorType":"exception","errorClass":"NotConfigured","httpStatus":null,"severity":"error","filePath":"scrapy/core/downloader/handlers/_base_streaming.py","lineNumber":70,"sourceCode":"    headers: Headers\n    certificate: NotRequired[Any]\n    ip_address: NotRequired[IPv4Address | IPv6Address | None]\n    protocol: str | None\n\n\nclass BaseStreamingDownloadHandler(BaseHttpDownloadHandler, ABC, Generic[_ResponseT]):\n    \"\"\"A base class for HTTP download handlers that follow the streaming logic flow.\"\"\"\n\n    _DEFAULT_CONNECT_TIMEOUT: ClassVar[float] = 10\n    experimental: ClassVar[bool] = False\n    requires_asyncio: ClassVar[bool] = True\n    # require subclasses to disable proxies explicitly with an explanation\n    supports_proxies: ClassVar[bool] = True\n    supports_per_request_bindaddress: ClassVar[bool] = False\n\n    def __init__(self, crawler: Crawler):\n        if self.requires_asyncio and not is_asyncio_available():  # pragma: no cover\n            raise NotConfigured(\n                f\"{type(self).__name__} requires the asyncio support. Make\"\n                f\" sure that you have either enabled the asyncio Twisted\"\n                f\" reactor in the TWISTED_REACTOR setting or disabled the\"\n                f\" TWISTED_REACTOR_ENABLED setting. See the asyncio documentation\"\n                f\" of Scrapy for more information.\"\n            )\n        self._check_deps_installed()\n        super().__init__(crawler)\n        if self.experimental:\n            logger.warning(\n                f\"{type(self).__name__} is experimental and is not recommended for production use.\"\n            )\n        self._bind_address = normalize_bind_address(\n            crawler.settings.get(\"DOWNLOAD_BIND_ADDRESS\")\n        )\n        self._proxy_auth_encoding: str = crawler.settings.get(\"HTTPPROXY_AUTH_ENCODING\")\n        # these are useful for many handlers but used in different ways by them\n        self._pool_size_total: int = crawler.settings.getint(\"CONCURRENT_REQUESTS\")","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/scrapy/scrapy/blob/06af687662112027b4482d31e2714a3cf280a91f/scrapy/core/downloader/handlers/_base_streaming.py#L52-L88","documentation":"Streaming download handlers (the new async streaming HTTP handlers, e.g. the experimental ones) require Scrapy running on the asyncio Twisted reactor. Their __init__ checks is_asyncio_available() — true only when TWISTED_REACTOR selects the asyncio reactor or TWISTED_REACTOR_ENABLED is false — and raises NotConfigured with this message otherwise. Because it is NotConfigured, the handler is skipped at startup and the failure surfaces later as an unsupported-scheme download error.","triggerScenarios":"Setting DOWNLOAD_HANDLERS to a BaseStreamingDownloadHandler subclass while keeping the default (non-asyncio) Twisted reactor; running on Windows with the old default reactor; TWISTED_REACTOR explicitly set to a non-asyncio reactor such as 'twisted.internet.default:selectreactor'.","commonSituations":"Adopting the new streaming handlers without the required reactor migration; custom settings bundles (e.g. company baselines) that pin the default reactor; upgrading Scrapy where TWISTED_REACTOR defaults changed and overrides now conflict.","solutions":["Enable the asyncio reactor: TWISTED_REACTOR = 'twisted.internet.asyncioreactor.AsyncioSelectorReactor' in settings.","Or set TWISTED_REACTOR_ENABLED = False to let Scrapy manage reactor selection (asyncio used by default in recent versions).","If you must stay on the default reactor, revert the DOWNLOAD_HANDLERS override to the classic handler for that scheme."],"exampleFix":"# before\nDOWNLOAD_HANDLERS = {\n    'https': 'myproj.handlers.MyStreamingHandler',\n}\n# TWISTED_REACTOR unset -> NotConfigured: requires the asyncio support\n\n# after\nTWISTED_REACTOR = 'twisted.internet.asyncioreactor.AsyncioSelectorReactor'\nDOWNLOAD_HANDLERS = {\n    'https': 'myproj.handlers.MyStreamingHandler',\n}","handlingStrategy":"validation","validationCode":"from scrapy.utils.reactor import is_asyncio_available\nimport scrapy\nfrom scrapy.utils.test import get_crawler\n\nassert is_asyncio_available(), (\n    \"set TWISTED_REACTOR='twisted.internet.asyncioreactor.AsyncioSelectorReactor' \"\n    \"before using streaming handlers\"\n)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Set the asyncio reactor in settings whenever you enable streaming handlers.","Install the correct reactor once at process start; changing reactors mid-process is unsupported.","Watch logs at startup: a NotConfigured handler is skipped silently and only fails later as unsupported scheme."],"tags":["downloader","asyncio","reactor","configuration","streaming-handlers"],"backgroundTag":null,"analyzedSha":"06af687662112027b4482d31e2714a3cf280a91f","analyzedAt":"2026-08-15T00:21:48.041Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}