ytdl-org/youtube-dl · error · ExtractorError
This video is DRM protected.
Error message
This video is DRM protected.
What it means
Raised by TV2IE when the video metadata from tv2.no marks the asset as drmProtected and no playable formats could be extracted (all MPD/HLS/plain-URL extraction yielded nothing). It is an expected ExtractorError, so youtube-dl reports it as a user-facing 'video unavailable' rather than a bug. DRM content is encrypted and cannot be downloaded by youtube-dl.
Source
Thrown at youtube_dl/extractor/tv2.py:106
if not data.get('drmProtected'):
formats.extend(self._extract_m3u8_formats(
video_url, video_id, 'mp4',
'm3u8' if is_live else 'm3u8_native',
m3u8_id=format_id, fatal=False))
elif ext == 'mpd':
formats.extend(self._extract_mpd_formats(
video_url, video_id, format_id, fatal=False))
elif ext == 'ism' or video_url.endswith('.ism/Manifest'):
pass
else:
formats.append({
'url': video_url,
'format_id': format_id,
'tbr': int_or_none(item.get('bitrate')),
'filesize': int_or_none(item.get('fileSize')),
})
if not formats and data.get('drmProtected'):
raise ExtractorError('This video is DRM protected.', expected=True)
self._sort_formats(formats)
thumbnails = [{
'id': thumbnail.get('@type'),
'url': thumbnail.get('url'),
} for _, thumbnail in (asset.get('imageVersions') or {}).items()]
return {
'id': video_id,
'url': video_url,
'title': self._live_title(title) if is_live else title,
'description': strip_or_none(asset.get('description')),
'thumbnails': thumbnails,
'timestamp': parse_iso8601(asset.get('createTime')),
'duration': float_or_none(asset.get('accurateDuration') or asset.get('duration')),
'view_count': int_or_none(asset.get('views')),
'categories': asset.get('keywords', '').split(','),
'formats': formats,View on GitHub (pinned to 956b8c5855)
Solutions
- Accept that DRM-protected TV2 content cannot be downloaded with youtube-dl; use the broadcaster's official app/portal.
- Verify the video actually plays without entitlements in a browser on the same network/cookies; if the page itself refuses, nothing youtube-dl can do.
- Try a different, non-DRM episode/clip ID from the same show.
- Pass --cookies from an authenticated browser session if the asset requires login (only helps for non-DRM paywalls).
Defensive patterns
Strategy: try-catch
Type guard
def is_tv2_drm(data: dict) -> bool:
return not data.get('formats') and bool(data.get('drmProtected')) Try / catch
from youtube_dl.utils import ExtractorError
try:
ydl.extract_info('https://www.tv2.no/video/1234567/')
except ExtractorError as e:
if 'DRM protected' in str(e):
log.warning('Skipping DRM item: %s', e)
else:
raise Prevention
- Treat 'DRM protected' as a terminal per-item condition; exclude such ids from retry queues.
- In batch pipelines, catch ExtractorError per URL and record the reason instead of aborting the run.
When it happens
Trigger: Requesting a tv2.no (or TV 2 Sumo) URL whose asset JSON contains data['drmProtected'] == true while every candidate video_url produced zero formats (e.g. only .ism/Manifest entries, which are skipped with 'pass').
Common situations: Premium/licensed broadcasts on TV2 Norway, Hollywood movies or live sports behind DRM licensing, region-locked assets that only expose PlayReady/Widevine manifests.
Related errors
- Video %s is DRM protected
- This video is DRM protected.
- This video is DRM protected.
- This video is DRM protected.
- This video is DRM protected.
AI-assisted analysis of ytdl-org/youtube-dl@956b8c5855 (2026-08-14).
Data as JSON: /api/errors/d37c1e8b5bab9ad2.
Report an issue: GitHub.