ytdl-org/youtube-dl · error · ExtractorError
No stream data/URL
Error message
No stream data/URL
What it means
Raised by the GB News extractor after fetching <api_hostname>/api/<type>/stream/<uvid> when response.stream is missing or not a valid URL (traverse_obj with url_or_none filter). The stream request uses fatal=False, so HTTP failures also arrive here with stream_data set to None.
Source
Thrown at youtube_dl/extractor/gbnews.py:114
uvid = video_data['data-uvid']
dtype = video_data.get('data-type')
stream_data = self._download_json(
'%s/api/%s/stream/%s' % (meta_url, 'show' if dtype == 'vod' else dtype, uvid),
uvid,
query={
'key': video_data.get('data-key'),
'platform': self._PLATFORM,
},
headers={
'Token': video_data.get('data-token'),
'Token-Expiry': video_data.get('data-expiry'),
'Uvid': uvid,
}, fatal=False)
stream_url = traverse_obj(stream_data, (
'response', 'stream', T(url_or_none)))
if not stream_url:
raise ExtractorError('No stream data/URL')
# now known to be a dict
stream_data = stream_data['response']
drm = stream_data.get('drm')
if drm:
self.report_drm(uvid)
formats = self._extract_m3u8_formats(
stream_url, uvid, ext='mp4', entry_protocol='m3u8_native',
fatal=False)
# exception if no formats
self._sort_formats(formats)
return {
'id': uvid,
'display_id': display_id,
'title': (traverse_obj(stream_data, ('title', T(txt_or_none)))
or self._og_search_title(webpage, default=None)View on GitHub (pinned to 956b8c5855)
Solutions
- Re-download the page fresh (clear cache) so data-token/data-expiry are current and retry
- Run with -v to confirm the stream API request/response behind the swallowed failure
- Check geo/VPN: GB News streams are typically UK-only
- Update youtube-dl/yt-dlp; if still failing, extract the stream URL manually from devtools
Defensive patterns
Strategy: try-catch
Validate before calling
import requests
r = requests.get(f'{api_hostname}/api/{dtype}/stream/{uvid}', headers=hdrs, params={'platform': 'gbnews'})
stream = r.json().get('response', {}).get('stream')
if not isinstance(stream, str) or not stream.startswith('http'):
print('Stream endpoint returned no playable URL (token/geo/DRM?)') Type guard
from youtube_dl.utils import url_or_none
def stream_url_ok(stream_data):
return url_or_none(stream_data and stream_data.get('response', {}).get('stream')) is not None Try / catch
try:
info = ydl.extract_info(url)
except DownloadError as e:
if 'No stream data/URL' in str(e):
refetch_page_and_retry(url) # tokens in the page may be stale
else:
raise Prevention
- Always fetch the page fresh immediately before extraction so data-token/data-expiry are current
- Use a UK exit for GB News streams
- Accept that DRM-flagged responses cannot be downloaded
When it happens
Trigger: The stream API rejects the Token/Token-Expiry/Uvid headers (expired token from the page), returns DRM-only or geo-blocked content with no stream URL, or the request failed silently due to fatal=False.
Common situations: Stale page HTML with expired tokens (page cached long before extraction), geo-restriction to the UK, DRM-protected streams, or an API response-shape change by Simplestream.
Related errors
- Video %s is not available
- error['error_description']
- %s returned error: %s
- %s said: %s
- This content is not available at your territory due to limit
AI-assisted analysis of ytdl-org/youtube-dl@956b8c5855 (2026-08-14).
Data as JSON: /api/errors/a2e38360a9cbd7c5.
Report an issue: GitHub.