ytdl-org/youtube-dl · warning · JSInterpreter.Exception
Signature function returned an exception
Error message
Signature function returned an exception
What it means
Raised as JSInterpreter.Exception inside extract_nsig when the executed nsig function returns a value that starts with 'enhanced_except_' (the JS function's own error marker) or ends with the input string s (meaning the 'decryption' is an identity — it failed to transform the parameter). Both outcomes mean the extracted function did not actually decrypt the n parameter.
Source
Thrown at youtube_dl/extractor/youtube.py:2123
func_code = self._extract_sig_fn(jsi, func_name)
if player_url:
self._store_player_data_to_cache('nsig', player_url, func_code)
return jsi, player_id, func_code
def _extract_n_function_from_code(self, jsi, func_code):
func = jsi.extract_function_from_code(*func_code)
def extract_nsig(s):
try:
ret = func([s], kwargs={'_ytdl_do_not_return': s})
except JSInterpreter.Exception:
raise
except Exception as e:
raise JSInterpreter.Exception(traceback.format_exc(), cause=e)
if ret.startswith('enhanced_except_') or ret.endswith(s):
raise JSInterpreter.Exception('Signature function returned an exception')
return ret
return extract_nsig
def _unthrottle_format_urls(self, video_id, player_url, *formats):
def decrypt_nsig(n):
return self._cached(self._decrypt_nsig, 'nsig', n, player_url)
for fmt in formats:
n_param = parse_qs(fmt['url']).get('n')
if not n_param:
continue
n_param = n_param[-1]
n_response = decrypt_nsig(n_param)(n_param, video_id, player_url)
if n_response is None:
# give up and forget cached data if descrambling failed
self._remove_player_data_from_cache('nsig', player_url)View on GitHub (pinned to 956b8c5855)
Solutions
- Update youtube-dl / move to yt-dlp — wrong-function extraction is fixed by pattern updates.
- Clear the nsig function cache so a stale wrong function is not reused.
- If developing, verify _extract_n_function_code's function identification against the current base.js and test with the known failing n value.
- Tolerate the resulting throttle warning short-term: URLs still work, just slower.
Defensive patterns
Strategy: retry
Validate before calling
def nsig_result_ok(ret: str, s: str) -> bool:
return not (ret.startswith('enhanced_except_') or ret.endswith(s)) Try / catch
try:
ret = extract_nsig(n)
except JSInterpreter.Exception as e:
if 'Signature function returned an exception' in str(e):
clear_player_cache(player_url) # wrong function cached
return extract_nsig_fresh(n) # re-extract and retry once
raise Prevention
- Verify decrypted values differ from input and lack the enhanced_except_ prefix during development.
- Invalidate the nsig cache whenever the player version changes to avoid replaying a wrong function.
When it happens
Trigger: The regex/interpreter extracted the wrong function or partially evaluated it (e.g. matched a decoy function, or the interpreter took an early-return branch), so calling func([s]) yields the input unchanged or the enhanced_except_ marker. Occurs per n-value during _unthrottle_format_urls.
Common situations: YouTube adds decoy similarly-named functions or restructures code so the extraction grabs the wrong one; interpreter shortcuts (like the _ytdl_do_not_return guard) reveal identity results; new player versions after youtube-dl's last patch.
Related errors
- traceback.format_exc() (dynamic; surfaces in 'Unable to deco
- Cannot decrypt nsig without player_url
- Unable to extract nsig function code
- No login info available, needed for using %s.
- Cannot identify player %r
AI-assisted analysis of ytdl-org/youtube-dl@956b8c5855 (2026-08-14).
Data as JSON: /api/errors/2bef16fb5757f2b7.
Report an issue: GitHub.