yt-dlp/yt-dlp · error · ExtractorError
Got empty response from playback API
Error message
Got empty response from playback API
What it means
OnDemandKoreaIE calls odkmedia.io's v3 playback API with 403/404 whitelisted via expected_status, so HTTP errors come back as JSON. When the response has no 'result' object it surfaces the API's own message (messages.__default or title) or falls back to 'Got empty response from playback API', always with expected=True. The generic text appears only when the error envelope carries no readable message; the usual causes are regional licensing (403) or removed/wrong contentId (404).
Source
Thrown at yt_dlp/extractor/ondemandkorea.py:80
'duration': 7267.0,
'title': 'The Outlaws: Main Movie',
'thumbnail': r're:^https?://.*\.(jpg|jpeg|png)',
'age_limit': 18,
},
}, {
'url': 'https://www.ondemandkorea.com/en/player/vod/capture-the-moment-how-is-that-possible?contentId=1605006',
'only_matching': True,
}]
def _real_extract(self, url):
video_id = self._match_id(url)
data = self._download_json(
f'https://odkmedia.io/odx/api/v3/playback/{video_id}/', video_id, fatal=False,
headers={'service-name': 'odk'}, query={'did': str(uuid.uuid4())}, expected_status=(403, 404))
if not traverse_obj(data, ('result', {dict})):
msg = traverse_obj(data, ('messages', '__default'), 'title', expected_type=str)
raise ExtractorError(msg or 'Got empty response from playback API', expected=True)
data = data['result']
def try_geo_bypass(url):
return traverse_obj(url, ({parse_qs}, 'stream_url', 0, {url_or_none})) or url
formats = []
for m3u8_url in traverse_obj(data, (('sources', 'manifest'), ..., 'url', {url_or_none}, {try_geo_bypass})):
mod_url = re.sub(r'_720(p?)\.m3u8', r'_1080\1.m3u8', m3u8_url)
if mod_url != m3u8_url:
mod_format = self._extract_m3u8_formats(
mod_url, video_id, note='Checking for higher quality format',
errnote='No higher quality format found', fatal=False)
if mod_format:
formats.extend(mod_format)
continue
formats.extend(self._extract_m3u8_formats(m3u8_url, video_id, fatal=False))
View on GitHub (pinned to 81ecd58b13)
Solutions
- Read the full error line first — when present, the API's own message (messages.__default) states the real reason (region vs removed).
- Route through an egress IP in a licensed region if you are entitled to the content.
- Re-resolve the contentId from the current OnDemandKorea page URL; stale ids return empty results.
- Confirm the title still exists on the site; if yes and it still fails on latest yt-dlp, report with -v.
Example fix
# before — stale contentId / wrong region yt-dlp 'https://www.ondemandkorea.com/en/player/vod/some-title?contentId=1605006' # after — refresh contentId from the site and run from a licensed region yt-dlp --proxy 'http://us-proxy.example:8080' 'https://www.ondemandkorea.com/en/player/vod/some-title?contentId=<current-id>'
Defensive patterns
Strategy: try-catch
Type guard
from yt_dlp.utils import DownloadError
def is_odk_playback_empty(e: BaseException) -> bool:
return isinstance(e, DownloadError) and 'Got empty response from playback API' in str(e) Try / catch
from yt_dlp import YoutubeDL
from yt_dlp.utils import DownloadError
try:
with YoutubeDL({'quiet': True}) as ydl:
ydl.extract_info(url, download=True)
except DownloadError as e:
if 'Got empty response from playback API' in str(e):
refresh_content_id_and_egress(url) # geo or removed: change egress / re-resolve id, retry once
else:
raise Prevention
- Run OnDemandKorea jobs from IPs in licensed regions.
- Resolve contentIds fresh from the site URL before each download; never hard-code them long-term.
- Keep the API-provided message in logs when present — it distinguishes geo blocks from removals.
When it happens
Trigger: The playback API answers 403 (region not licensed for the title), 404 (removed or stale contentId), or 200 with an error envelope lacking messages.__default/title — the last case produces exactly the generic message.
Common situations: Viewers outside ODK's licensed regions without a matching egress IP; deep links with stale contentIds after catalog reshuffles; transient ODK API incidents.
Related errors
- {self.IE_NAME} said: {message}
- {} said: {}
- Unable to load data. Error code: {code}
- Unable to download video %s
- Iwara API said: {error or "nothing"}
AI-assisted analysis of yt-dlp/yt-dlp@81ecd58b13 (2026-08-22).
Data as JSON: /api/errors/dd8bd181d7315e1b.
Report an issue: GitHub.