ytdl-org/youtube-dl · error · ExtractorError
Video %s is not available
Error message
Video %s is not available
What it means
Raised by the Arte extractor when the player config JSON (videoJsonPlayer) contains no VSR (Video Source References) entry. If the API supplied custom_msg with type 'error', that message is used instead; otherwise the generic 'Video %s is not available' is raised with the VID. Marked expected=True.
Source
Thrown at youtube_dl/extractor/arte.py:69
def _real_extract(self, url):
mobj = re.match(self._VALID_URL, url)
video_id = mobj.group('id')
lang = mobj.group('lang') or mobj.group('lang_2')
info = self._download_json(
'%s/config/%s/%s' % (self._API_BASE, lang, video_id), video_id)
player_info = info['videoJsonPlayer']
vsr = try_get(player_info, lambda x: x['VSR'], dict)
if not vsr:
error = None
if try_get(player_info, lambda x: x['custom_msg']['type']) == 'error':
error = try_get(
player_info, lambda x: x['custom_msg']['msg'], compat_str)
if not error:
error = 'Video %s is not available' % player_info.get('VID') or video_id
raise ExtractorError(error, expected=True)
upload_date_str = player_info.get('shootingDate')
if not upload_date_str:
upload_date_str = (player_info.get('VRA') or player_info.get('VDA') or '').split(' ')[0]
title = (player_info.get('VTI') or player_info['VID']).strip()
subtitle = player_info.get('VSU', '').strip()
if subtitle:
title += ' - %s' % subtitle
qfunc = qualities(['MQ', 'HQ', 'EQ', 'SQ'])
LANGS = {
'fr': 'F',
'de': 'A',
'en': 'E[ANG]',
'es': 'E[ESP]',
'it': 'E[ITA]',View on GitHub (pinned to 956b8c5855)
Solutions
- If custom_msg was shown, follow its text (usually expiry or geo reason)
- Retry from a DE/FR IP for geo-restricted items
- Try the other language variant of the URL (arte.fr vs arte.de) which can have different availability
- For expired content, look for a rebroadcast with a fresh video id
Defensive patterns
Strategy: try-catch
Validate before calling
# Optional: probe the Arte config for VSR before full extraction
import requests
cfg = requests.get('https://api.arte.tv/api/player/v1/config/de/%s' % video_id).json()
player = cfg.get('videoJsonPlayer', {})
if not player.get('VSR'):
reason = (player.get('custom_msg') or {}).get('msg', 'no VSR')
skip(url, reason=reason) Try / catch
try:
ydl.extract_info(url)
except ExtractorError as e:
msg = str(e)
if 'not available' in msg:
if is_geo_reason(msg):
requeue_with_region(url, 'DE') # or 'FR'
else:
mark_url_dead(url) # expired arte+7 content Prevention
- Download arte content within its availability window (often 7 days after broadcast)
- Match the URL's language variant (arte.de vs arte.fr) — availability can differ per language
- Route through a DE/FR IP when content is geo-locked
When it happens
Trigger: GET <API_BASE>/config/<lang>/<video_id> returns videoJsonPlayer without VSR; geo-restricted arte content viewed from outside allowed regions; content past its streaming window; custom_msg type 'error' carrying the site's reason.
Common situations: Extracting arte+7 content after its 7-day expiry; watching French/German-locked items from other countries; lang parameter (de/fr) mismatch for a language-exclusive item.
Related errors
- Video %s does not exist
- Video %s is no longer available
- Show not found in A&E feed (too new?)
- Video %s has been deleted
- %s said: %s
AI-assisted analysis of ytdl-org/youtube-dl@956b8c5855 (2026-08-14).
Data as JSON: /api/errors/0210fd2ca2b29af5.
Report an issue: GitHub.