{"record":{"id":"fd5abc17b22e7d3d","repo":"yt-dlp/yt-dlp","slug":"pycryptodomex-not-found-please-install","errorCode":null,"errorMessage":"pycryptodomex not found. Please install","messagePattern":"pycryptodomex not found\\. Please install","errorType":"exception","errorClass":"ExtractorError","httpStatus":null,"severity":"error","filePath":"yt_dlp/extractor/bilibili.py","lineNumber":2235,"sourceCode":"                'vcodec': 'none',\n                'filesize': aud.get('size'),\n            })\n\n        return formats\n\n    def _parse_video_metadata(self, video_data):\n        return {\n            'title': video_data.get('title_display') or video_data.get('title'),\n            'description': video_data.get('desc'),\n            'thumbnail': video_data.get('cover'),\n            'timestamp': unified_timestamp(video_data.get('formatted_pub_date')),\n            'episode_number': int_or_none(self._search_regex(\n                r'^E(\\d+)(?:$| - )', video_data.get('title_display') or '', 'episode number', default=None)),\n        }\n\n    def _perform_login(self, username, password):\n        if not Cryptodome.RSA:\n            raise ExtractorError('pycryptodomex not found. Please install', expected=True)\n\n        key_data = self._download_json(\n            'https://passport.bilibili.tv/x/intl/passport-login/web/key?lang=en-US', None,\n            note='Downloading login key', errnote='Unable to download login key')['data']\n\n        public_key = Cryptodome.RSA.importKey(key_data['key'])\n        password_hash = Cryptodome.PKCS1_v1_5.new(public_key).encrypt((key_data['hash'] + password).encode())\n        login_post = self._download_json(\n            'https://passport.bilibili.tv/x/intl/passport-login/web/login/password?lang=en-US', None,\n            data=urlencode_postdata({\n                'username': username,\n                'password': base64.b64encode(password_hash).decode('ascii'),\n                'keep_me': 'true',\n                's_locale': 'en_US',\n                'isTrusted': 'true',\n            }), note='Logging in', errnote='Unable to log in')\n        if login_post.get('code'):\n            if login_post.get('message'):","sourceCodeStart":2217,"sourceCodeEnd":2253,"githubUrl":"https://github.com/yt-dlp/yt-dlp/blob/81ecd58b1394793e6da9998cc19fdb45657f1685/yt_dlp/extractor/bilibili.py#L2217-L2253","documentation":"BiliIntl login (netrc machine biliintl) encrypts the password with RSA before posting to passport.bilibili.tv; the crypto lives in the optional dependency pycryptodomex. When it is not installed, Cryptodome.RSA is None and _perform_login aborts immediately with this expected error before any network call. Extraction without login still works - only credential-based login is blocked.","triggerScenarios":"Running yt-dlp --username/--password on a bilibili.tv URL in an environment where the pycryptodomex wheel was never installed: bare 'pip install yt-dlp' without extras, slim containers, or distro packages that split the crypto module out.","commonSituations":"CI/docker images built from the minimal wheel; venvs migrated without requirements; switching machines and forgetting the optional dependency.","solutions":["Install the dependency: python3 -m pip install -U pycryptodomex (or pip install -U 'yt-dlp[default]').","Or bypass password login entirely: yt-dlp --cookies-from-browser firefox <url> works without the crypto module.","Verify with: python3 -c \"from Cryptodome.PublicKey import RSA; print('ok')\"."],"exampleFix":"# before\nyt-dlp --username user --password pass 'https://www.bilibili.tv/en/play/34613/341736'\n# ERROR: pycryptodomex not found. Please install\n\n# after\npython3 -m pip install -U pycryptodomex\nyt-dlp --username user --password pass 'https://www.bilibili.tv/en/play/34613/341736'","handlingStrategy":"validation","validationCode":"def biliintl_login_available():\n    try:\n        from Cryptodome.PublicKey import RSA  # noqa: F401\n        return True\n    except ImportError:\n        return False\n\nif args.username and not biliintl_login_available():\n    sys.exit('Install pycryptodomex, or use --cookies instead of --username')","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Install yt-dlp with the default extra (pip install 'yt-dlp[default]') in any image that will do logins.","Prefer --cookies-from-browser over password login - it needs no crypto dependency.","Pin pycryptodomex in requirements for scripts that use --username against bilibili.tv."],"tags":["missing-dependency","pycryptodomex","bilibili-intl","login","yt-dlp"],"backgroundTag":"missing-optional-dependency","analyzedSha":"81ecd58b1394793e6da9998cc19fdb45657f1685","analyzedAt":"2026-08-22T12:21:25.439Z","schemaVersion":2},"datasetVersion":"2026-08-22T14:17:55.899Z"}