{"record":{"id":"9f3a9cab5c640e5f","repo":"ytdl-org/youtube-dl","slug":"cannot-extract-signature-timestamp-without-player","errorCode":null,"errorMessage":"Cannot extract signature timestamp without player url","messagePattern":"Cannot extract signature timestamp without player url","errorType":"exception","errorClass":"ExtractorError","httpStatus":null,"severity":"error","filePath":"youtube_dl/extractor/youtube.py","lineNumber":2164,"sourceCode":"    def _extract_signature_timestamp(self, video_id, player_url, ytcfg=None, fatal=False):\n        \"\"\"\n        Extract signatureTimestamp (sts)\n\n        Required to tell API what sig/player version is in use.\n        \"\"\"\n        sts = traverse_obj(\n            (self._get_player_js_version(), ytcfg),\n            (0, 0),\n            (1, 'STS'),\n            expected_type=int_or_none)\n\n        if sts:\n            return sts\n\n        if not player_url:\n            error_msg = 'Cannot extract signature timestamp without player url'\n            if fatal:\n                raise ExtractorError(error_msg)\n            self.report_warning(error_msg)\n            return None\n\n        sts = self._load_player_data_from_cache('sts', player_url)\n        if sts:\n            return sts\n\n        # Attempt to extract from player\n        code = self._load_player(video_id, player_url, fatal=fatal)\n        sts = int_or_none(self._search_regex(\n            r'(?:signatureTimestamp|sts)\\s*:\\s*(?P<sts>[0-9]{5})', code or '',\n            'JS player signature timestamp', group='sts', fatal=fatal))\n        if sts:\n            self._store_player_data_to_cache('sts', player_url, sts)\n\n        return sts\n\n    def _mark_watched(self, video_id, player_response):","sourceCodeStart":2146,"sourceCodeEnd":2182,"githubUrl":"https://github.com/ytdl-org/youtube-dl/blob/956b8c585591b401a543e409accb163eeaaa1193/youtube_dl/extractor/youtube.py#L2146-L2182","documentation":"Raised by YoutubeIE's signature-timestamp helper (used around embed/age-gate flows) when no STS could be obtained from the cached player JS version or ytcfg, and player_url is None so the player JS cannot be loaded to search for signatureTimestamp. With fatal=True it raises; otherwise it only warns and returns None.","triggerScenarios":"Requesting player data for an embedded/age-restricted video where neither _get_player_js_version()/ytcfg['STS'] nor cache yields a timestamp, and the caller passed no player_url — typical when the player config scrape failed upstream.","commonSituations":"Age-gated videos fetched without cookies; YouTube page changes removing the STS from ytcfg; third-party embeds where the player URL is absent from the response.","solutions":["Ensure the page/player response that contains the player URL is fetched (cookies for age-gated content) before STS extraction.","Update youtube-dl — the STS fallback chain (ytcfg key, player JS regex '(?:signatureTimestamp|sts)\\s*:\\s*[0-9]{5}') is patched when YouTube moves it.","If calling internally, pass fatal=False when a missing STS should degrade gracefully.","Provide cookies via --cookies so the full player config, including player_url and STS, is present."],"exampleFix":"// before\nsts = self._extract_signature_timestamp(video_id, player_url=None, fatal=True)\n\n// after\nplayer_url = self._extract_player_url(ytcfg, webpage) or fatal_player_url\nsts = self._extract_signature_timestamp(video_id, player_url, fatal=False)","handlingStrategy":"fallback","validationCode":"sts = traverse_obj((self._get_player_js_version(), ytcfg), (0, 0), (1, 'STS'), expected_type=int_or_none)\nif not sts and player_url is None:\n    player_url = self._extract_player_url(ytcfg, webpage)  # resolve before STS call","typeGuard":null,"tryCatchPattern":"try:\n    sts = self._extract_signature_timestamp(video_id, player_url)\nexcept ExtractorError as e:\n    if 'without player url' in str(e):\n        return None  # degrade: proceed without STS where the flow allows\n    raise","preventionTips":["Pass fatal=False where a missing STS should not abort the request.","Ensure cookies/player response are present so both ytcfg['STS'] and player_url are available."],"tags":["youtube","sts","signature","player-url"],"backgroundTag":null,"analyzedSha":"956b8c585591b401a543e409accb163eeaaa1193","analyzedAt":"2026-08-14T18:59:47.863Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}