{"record":{"id":"b125bba77f884e01","repo":"ytdl-org/youtube-dl","slug":"video-s-is-drm-protected","errorCode":null,"errorMessage":"Video %s is DRM protected","messagePattern":"Video (.+?) is DRM protected","errorType":"exception","errorClass":"ExtractorError","httpStatus":null,"severity":"error","filePath":"youtube_dl/extractor/tvnow.py","lineNumber":71,"sourceCode":"                if hd_url != urls[0]:\n                    urls.append(hd_url)\n                return urls\n\n            for man_url in make_urls('dash', '.mpd'):\n                formats = self._extract_mpd_formats(\n                    man_url, video_id, mpd_id='dash', fatal=False)\n            for man_url in make_urls('hss', 'Manifest'):\n                formats.extend(self._extract_ism_formats(\n                    man_url, video_id, ism_id='mss', fatal=False))\n            for man_url in make_urls('hls', '.m3u8'):\n                formats.extend(self._extract_m3u8_formats(\n                    man_url, video_id, 'mp4', 'm3u8_native', m3u8_id='hls',\n                    fatal=False))\n            if formats:\n                break\n        else:\n            if info.get('isDrm'):\n                raise ExtractorError(\n                    'Video %s is DRM protected' % video_id, expected=True)\n            if info.get('geoblocked'):\n                raise self.raise_geo_restricted()\n            if not info.get('free', True):\n                raise ExtractorError(\n                    'Video %s is not available for free' % video_id, expected=True)\n        self._sort_formats(formats)\n\n        description = info.get('articleLong') or info.get('articleShort')\n        timestamp = parse_iso8601(info.get('broadcastStartDate'), ' ')\n        duration = parse_duration(info.get('duration'))\n\n        f = info.get('format', {})\n\n        thumbnails = [{\n            'url': 'https://aistvnow-a.akamaihd.net/tvnow/movie/%s' % video_id,\n        }]\n        thumbnail = f.get('defaultImage169Format') or f.get('defaultImage169Logo')","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/ytdl-org/youtube-dl/blob/956b8c585591b401a543e409accb163eeaaa1193/youtube_dl/extractor/tvnow.py#L53-L89","documentation":"Raised by TVNowIE (old api.tvnow.de path) when no formats could be extracted from any of the mpd/hss/hls manifest URLs and the API metadata flags info['isDrm']. It means the episode is delivered only with DRM (Widevine/PlayReady) and youtube-dl cannot process it. Expected error: presented to the user as content unavailability.","triggerScenarios":"Extracting a tvnow.de/.at/.ch episode where all _extract_mpd_formats/_extract_ism_formats/_extract_m3u8_formats calls return nothing (all fatal=False) and info.get('isDrm') is truthy.","commonSituations":"Premium RTL/TVM Now content (US series, movies) sold with studio DRM, previews whose manifests require a license server, new-style URLs that the old-API loophole no longer covers.","solutions":["Confirm the episode plays in a browser without a paid TVNOW subscription; DRM flagged items cannot be downloaded.","If you have a TVNOW subscription, try --cookies exported from the logged-in browser (only works where DRM is not applied).","Try the URL of a free/preview episode of the same show.","Switch to a maintained fork (yt-dlp) whose TVNowIE uses the new apigw.tvnow.de backend."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":"def tvnow_is_drm(info: dict) -> bool:\n    return bool(info.get('isDrm'))","tryCatchPattern":"try:\n    ydl.extract_info(tvnow_url)\nexcept ExtractorError as e:\n    if 'DRM protected' in str(e):\n        report_skip('drm', url)\n    else:\n        raise","preventionTips":["Classify DRM failures as permanent; never requeue them.","Check isDrm in fetched metadata when building course/show download lists."],"tags":["drm","extractor","tvnow","paywall","streaming"],"backgroundTag":null,"analyzedSha":"956b8c585591b401a543e409accb163eeaaa1193","analyzedAt":"2026-08-14T18:59:47.863Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}