yt-dlp/yt-dlp · error · ExtractorError

pycryptodomex not found. Please install

Error message

pycryptodomex not found. Please install

What it means

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.

Source

Thrown at yt_dlp/extractor/bilibili.py:2235

                'vcodec': 'none',
                'filesize': aud.get('size'),
            })

        return formats

    def _parse_video_metadata(self, video_data):
        return {
            'title': video_data.get('title_display') or video_data.get('title'),
            'description': video_data.get('desc'),
            'thumbnail': video_data.get('cover'),
            'timestamp': unified_timestamp(video_data.get('formatted_pub_date')),
            'episode_number': int_or_none(self._search_regex(
                r'^E(\d+)(?:$| - )', video_data.get('title_display') or '', 'episode number', default=None)),
        }

    def _perform_login(self, username, password):
        if not Cryptodome.RSA:
            raise ExtractorError('pycryptodomex not found. Please install', expected=True)

        key_data = self._download_json(
            'https://passport.bilibili.tv/x/intl/passport-login/web/key?lang=en-US', None,
            note='Downloading login key', errnote='Unable to download login key')['data']

        public_key = Cryptodome.RSA.importKey(key_data['key'])
        password_hash = Cryptodome.PKCS1_v1_5.new(public_key).encrypt((key_data['hash'] + password).encode())
        login_post = self._download_json(
            'https://passport.bilibili.tv/x/intl/passport-login/web/login/password?lang=en-US', None,
            data=urlencode_postdata({
                'username': username,
                'password': base64.b64encode(password_hash).decode('ascii'),
                'keep_me': 'true',
                's_locale': 'en_US',
                'isTrusted': 'true',
            }), note='Logging in', errnote='Unable to log in')
        if login_post.get('code'):
            if login_post.get('message'):

View on GitHub (pinned to 81ecd58b13)

Solutions

  1. Install the dependency: python3 -m pip install -U pycryptodomex (or pip install -U 'yt-dlp[default]').
  2. Or bypass password login entirely: yt-dlp --cookies-from-browser firefox <url> works without the crypto module.
  3. Verify with: python3 -c "from Cryptodome.PublicKey import RSA; print('ok')".

Example fix

# before
yt-dlp --username user --password pass 'https://www.bilibili.tv/en/play/34613/341736'
# ERROR: pycryptodomex not found. Please install

# after
python3 -m pip install -U pycryptodomex
yt-dlp --username user --password pass 'https://www.bilibili.tv/en/play/34613/341736'
Defensive patterns

Strategy: validation

Validate before calling

def biliintl_login_available():
    try:
        from Cryptodome.PublicKey import RSA  # noqa: F401
        return True
    except ImportError:
        return False

if args.username and not biliintl_login_available():
    sys.exit('Install pycryptodomex, or use --cookies instead of --username')

Prevention

When it happens

Trigger: 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.

Common situations: CI/docker images built from the minimal wheel; venvs migrated without requirements; switching machines and forgetting the optional dependency.

Related errors


AI-assisted analysis of yt-dlp/yt-dlp@81ecd58b13 (2026-08-22). Data as JSON: /api/errors/fd5abc17b22e7d3d. Report an issue: GitHub.