ytdl-org/youtube-dl · error · ExtractorError
Video %s is DRM protected
Error message
Video %s is DRM protected
What it means
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.
Source
Thrown at youtube_dl/extractor/tvnow.py:71
if hd_url != urls[0]:
urls.append(hd_url)
return urls
for man_url in make_urls('dash', '.mpd'):
formats = self._extract_mpd_formats(
man_url, video_id, mpd_id='dash', fatal=False)
for man_url in make_urls('hss', 'Manifest'):
formats.extend(self._extract_ism_formats(
man_url, video_id, ism_id='mss', fatal=False))
for man_url in make_urls('hls', '.m3u8'):
formats.extend(self._extract_m3u8_formats(
man_url, video_id, 'mp4', 'm3u8_native', m3u8_id='hls',
fatal=False))
if formats:
break
else:
if info.get('isDrm'):
raise ExtractorError(
'Video %s is DRM protected' % video_id, expected=True)
if info.get('geoblocked'):
raise self.raise_geo_restricted()
if not info.get('free', True):
raise ExtractorError(
'Video %s is not available for free' % video_id, expected=True)
self._sort_formats(formats)
description = info.get('articleLong') or info.get('articleShort')
timestamp = parse_iso8601(info.get('broadcastStartDate'), ' ')
duration = parse_duration(info.get('duration'))
f = info.get('format', {})
thumbnails = [{
'url': 'https://aistvnow-a.akamaihd.net/tvnow/movie/%s' % video_id,
}]
thumbnail = f.get('defaultImage169Format') or f.get('defaultImage169Logo')View on GitHub (pinned to 956b8c5855)
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.
Defensive patterns
Strategy: try-catch
Type guard
def tvnow_is_drm(info: dict) -> bool:
return bool(info.get('isDrm')) Try / catch
try:
ydl.extract_info(tvnow_url)
except ExtractorError as e:
if 'DRM protected' in str(e):
report_skip('drm', url)
else:
raise Prevention
- Classify DRM failures as permanent; never requeue them.
- Check isDrm in fetched metadata when building course/show download lists.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- This video is DRM protected.
- This video is DRM protected.
- This video is DRM protected.
- This video is DRM protected.
- Video %s is not available for free
AI-assisted analysis of ytdl-org/youtube-dl@956b8c5855 (2026-08-14).
Data as JSON: /api/errors/b125bba77f884e01.
Report an issue: GitHub.