{"record":{"id":"6023a11b54670194","repo":"ytdl-org/youtube-dl","slug":"this-video-is-drm-protected-6023a1","errorCode":null,"errorMessage":"This video is DRM protected.","messagePattern":"This video is DRM protected\\.","errorType":"exception","errorClass":"ExtractorError","httpStatus":null,"severity":"error","filePath":"youtube_dl/extractor/ruutu.py","lineNumber":205,"sourceCode":"                            'url': video_url,\n                            'width': width,\n                            'height': height,\n                            'tbr': tbr,\n                            'preference': preference,\n                        })\n\n        extract_formats(video_xml.find('./Clip'))\n\n        def pv(name):\n            node = find_xpath_attr(\n                video_xml, './Clip/PassthroughVariables/variable', 'name', name)\n            if node is not None:\n                return node.get('value')\n\n        if not formats:\n            drm = xpath_text(video_xml, './Clip/DRM', default=None)\n            if drm:\n                raise ExtractorError('This video is DRM protected.', expected=True)\n            ns_st_cds = pv('ns_st_cds')\n            if ns_st_cds != 'free':\n                raise ExtractorError('This video is %s.' % ns_st_cds, expected=True)\n\n        self._sort_formats(formats)\n\n        themes = pv('themes')\n\n        return {\n            'id': video_id,\n            'title': xpath_attr(video_xml, './/Behavior/Program', 'program_name', 'title', fatal=True),\n            'description': xpath_attr(video_xml, './/Behavior/Program', 'description', 'description'),\n            'thumbnail': xpath_attr(video_xml, './/Behavior/Startpicture', 'href', 'thumbnail'),\n            'duration': int_or_none(xpath_text(video_xml, './/Runtime', 'duration')) or int_or_none(pv('runtime')),\n            'age_limit': int_or_none(xpath_text(video_xml, './/AgeLimit', 'age limit')),\n            'upload_date': unified_strdate(pv('date_start')),\n            'series': pv('series_name'),\n            'season_number': int_or_none(pv('season_number')),","sourceCodeStart":187,"sourceCodeEnd":223,"githubUrl":"https://github.com/ytdl-org/youtube-dl/blob/956b8c585591b401a543e409accb163eeaaa1193/youtube_dl/extractor/ruutu.py#L187-L223","documentation":"Raised by the Ruutu (Finnish broadcaster Nelonen) extractor when no formats could be extracted and the clip XML contains a non-empty ./Clip/DRM element. The stream is DRM-protected and youtube-dl will not (and legally cannot) decrypt it. Expected=True.","triggerScenarios":"Extracting a ruutu.fi URL whose clip metadata declares DRM - typically premium/rental content or live channels wrapped in PlayReady/Widevine.","commonSituations":"Subscribers trying to archive paid Ruutu content; live TV channels; trial-period rentals after expiry.","solutions":["There is no fix: DRM content is intentionally not extractable by youtube-dl.","If you believe the content is free, check that the correct URL (non-DRM variant) is used.","Use the official Ruutu player/app for playback; report nothing - this is by design."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try:\n    ydl.extract_info(url)\nexcept ExtractorError as e:\n    if 'DRM protected' in str(e):\n        skip_permanently(video_id)  # by design not extractable\n    else:\n        raise","preventionTips":["Never queue DRM Ruutu content in automated downloaders - it can only fail.","Use the official Ruutu player for DRM content.","If you expected free content, double-check you have the right (non-premium) URL."],"tags":["ruutu","drm","protected-content","expected-error"],"backgroundTag":null,"analyzedSha":"956b8c585591b401a543e409accb163eeaaa1193","analyzedAt":"2026-08-14T18:59:47.863Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}