ytdl-org/youtube-dl · error · ExtractorError

Unable to extract nsig function code

Error message

Unable to extract nsig function code

What it means

A wrapping error raised in _decrypt_nsig when _extract_n_function_code fails for any reason (the original ExtractorError is chained as cause). _extract_n_function_code downloads the player JS and locates the nsig function; failure means the code could not be fetched or the function pattern was not found. The cause chain carries the precise underlying reason.

Source

Thrown at youtube_dl/extractor/youtube.py:1991

            self._extract_signature_function, 'sig', player_url, self._signature_cache_id(s))
        func = extract_sig(video_id, player_url, s)
        self._print_sig_code(func, s)
        return func(s)

    # from yt-dlp
    # See also:
    # 1. https://github.com/ytdl-org/youtube-dl/issues/29326#issuecomment-894619419
    # 2. https://code.videolan.org/videolan/vlc/-/blob/4fb284e5af69aa9ac2100ccbdd3b88debec9987f/share/lua/playlist/youtube.lua#L116
    # 3. https://github.com/ytdl-org/youtube-dl/issues/30097#issuecomment-950157377
    def _decrypt_nsig(self, n, video_id, player_url):
        """Turn the encrypted n field into a working signature"""
        if player_url is None:
            raise ExtractorError('Cannot decrypt nsig without player_url')

        try:
            jsi, player_id, func_code = self._extract_n_function_code(video_id, player_url)
        except ExtractorError as e:
            raise ExtractorError('Unable to extract nsig function code', cause=e)
        if self.get_param('youtube_print_sig_code'):
            self.to_screen('Extracted nsig function from {0}:\n{1}\n'.format(
                player_id, func_code[1]))

        try:
            extract_nsig = self._cached(self._extract_n_function_from_code, 'nsig func', player_url)
            ret = extract_nsig(jsi, func_code)(n)
        except JSInterpreter.Exception as e:
            self.report_warning(
                '%s (%s %s)' % (
                    'Unable to decode n-parameter: expect download to be blocked or throttled',
                    error_to_compat_str(e),
                    traceback.format_exc()),
                video_id=video_id)
            return

        self.write_debug('Decrypted nsig {0} => {1}'.format(n, ret))
        return ret

View on GitHub (pinned to 956b8c5855)

Solutions

  1. Update youtube-dl (or switch to yt-dlp) — nsig extraction patterns are among the most frequently patched parts of the extractor.
  2. Inspect the cause exception in the chain (raise from) to distinguish 'download failed' (network/404) from 'regex did not match' (pattern change).
  3. Retry after some time if the player rollout is transient — YouTube often serves mixed player versions during rollouts.
  4. For library users, catch this and fall back to using the un-decrypted URL (throttled download) rather than failing the whole extraction.
Defensive patterns

Strategy: fallback

Try / catch

try:
    jsi, player_id, func_code = self._extract_n_function_code(video_id, player_url)
except ExtractorError as e:
    # keep the original URL (throttled) instead of failing extraction
    self.report_warning('nsig extraction failed: %s' % error_to_compat_str(e))
    return None

Prevention

When it happens

Trigger: Calling _decrypt_nsig with a valid player_url where downloading the base.js fails (network, 404 after a player rollout) or the regex/JS traversal used to find the n function no longer matches YouTube's obfuscated code.

Common situations: YouTube changes the shape/location of the nsig function in player JS; an old youtube-dl against a new player; transient fetch failures of /s/player/.../base.js; datacenter IPs getting blocked from player JS.

Related errors


AI-assisted analysis of ytdl-org/youtube-dl@956b8c5855 (2026-08-14). Data as JSON: /api/errors/b11638f04c40911b. Report an issue: GitHub.