ytdl-org/youtube-dl · error · ExtractorError
%s returned error: %s
Error message
%s returned error: %s
What it means
Raised via BBCCoUkIE._raise_extractor_error after _download_media_selector has tried every media set in _MEDIA_SETS and each one raised a MediaSelectionError whose id was one of 'notukerror', 'geolocation', or 'selectionunavailable'. The message interpolates the extractor name (BBC iPlayer) and the last error id, e.g. 'BBC iPlayer returned error: geolocation'. It is expected=True, signalling a server-side availability restriction rather than a code defect.
Source
Thrown at youtube_dl/extractor/bbc.py:341
for connection in self._extract_connections(media):
cc_url = url_or_none(connection.get('href'))
if not cc_url:
continue
captions = self._download_xml(
cc_url, programme_id, 'Downloading captions', fatal=False)
if not isinstance(captions, compat_etree_Element):
continue
subtitles['en'] = [
{
'url': connection.get('href'),
'ext': 'ttml',
},
]
break
return subtitles
def _raise_extractor_error(self, media_selection_error):
raise ExtractorError(
'%s returned error: %s' % (self.IE_NAME, media_selection_error.id),
expected=True)
def _download_media_selector(self, programme_id):
last_exception = None
for media_set in self._MEDIA_SETS:
try:
return self._download_media_selector_url(
self._MEDIA_SELECTOR_URL_TEMPL % (media_set, programme_id), programme_id)
except BBCCoUkIE.MediaSelectionError as e:
if e.id in ('notukerror', 'geolocation', 'selectionunavailable'):
last_exception = e
continue
self._raise_extractor_error(e)
self._raise_extractor_error(last_exception)
def _download_media_selector_url(self, url, programme_id=None):
media_selection = self._download_json(View on GitHub (pinned to 956b8c5855)
Solutions
- For 'geolocation'/'notukerror': use a UK IP (UK VPN/relay) or accept that the programme is geo-restricted.
- For 'selectionunavailable': double-check the programme id from the URL; the episode may have been pulled — try the programme's episode list page for a current id.
- Retry later if the programme was just published and the selector backend has not caught up.
- If you control the caller, treat this error as expected (it is raised expected=True) and surface 'not available in your region' to end users instead of a stack trace.
Example fix
// before
last_exception = None
for media_set in self._MEDIA_SETS:
try:
return self._download_media_selector_url(self._MEDIA_SELECTOR_URL_TEMPL % (media_set, programme_id), programme_id)
except BBCCoUkIE.MediaSelectionError as e:
if e.id in ('notukerror', 'geolocation', 'selectionunavailable'):
last_exception = e
// after: annotate the geo case with actionable wording for end users
if last_exception is not None:
if last_exception.id in ('notukerror', 'geolocation'):
raise ExtractorError('BBC iPlayer programmes are only available in the UK (error: %s)' % last_exception.id, expected=True)
raise ExtractorError('%s returned error: %s' % (self.IE_NAME, last_exception.id), expected=True) Defensive patterns
Strategy: try-catch
Try / catch
try:
ydl.extract_info('https://www.bbc.co.uk/iplayer/episode/%s' % pid)
except ExtractorError as e:
if 'returned error: geolocation' in str(e) or 'returned error: notukerror' in str(e):
raise RegionBlocked('BBC programme %s requires a UK IP' % pid) from e
if 'returned error: selectionunavailable' in str(e):
raise NotFound('no media set for %s; check the episode id' % pid) from e
raise Prevention
- For UK-only content, route requests through a UK IP from the start.
- Check the programme still has a 'Watch' button on its page before extracting.
- Map the three known error ids to user-facing causes instead of surfacing raw extractor text.
When it happens
Trigger: Requesting media selector JSON for a programme whose id returns an error object: 'geolocation' when the request IP is outside the UK, 'notukerror' when the programme is UK-only and the caller is abroad, 'selectionunavailable' when no media set exists for that programme id. The loop in _download_media_selector only re-raises after all media sets fail with a retryable/terminal id in that tuple.
Common situations: Running the extractor from a non-UK IP against UK-only content (the dominant case); supplying a programme id that exists in one brand but not the media-selector backend; VPN exit nodes detected by the BBC; programme unpublished after the page went live.
Related errors
- Episode %s is not yet available
- Episode %s is no longer available
- Episode %s is not currently available
- error
- Unable to log in
AI-assisted analysis of ytdl-org/youtube-dl@956b8c5855 (2026-08-14).
Data as JSON: /api/errors/1aad5d69044ade49.
Report an issue: GitHub.