yt-dlp/yt-dlp · error · ExtractorError
Unable to extract video info
Error message
Unable to extract video info
What it means
Thrown by NaverIE._real_extract (yt_dlp/extractor/naver.py:203). The TVCAST API call GET /clips/<id>/play-info succeeded, but the response is missing clip.videoId (the real media id) or play.inKey (the playback access key); without both, the follow-up streams endpoint cannot even be requested.
Source
Thrown at yt_dlp/extractor/naver.py:203
'comment_count': int,
'duration': 69,
'thumbnail': r're:^https?://.*\.jpg',
},
'params': {'format': 'HLS_144P'},
}, {
'url': 'http://tvcast.naver.com/v/81652',
'only_matching': True,
}]
def _real_extract(self, url):
video_id = self._match_id(url)
data = self._call_api(f'/clips/{video_id}/play-info', video_id)
vid = traverse_obj(data, ('clip', 'videoId', {str}))
in_key = traverse_obj(data, ('play', 'inKey', {str}))
if not vid or not in_key:
raise ExtractorError('Unable to extract video info')
info = self._extract_video_info(video_id, vid, in_key)
info.update(traverse_obj(data, ('clip', {
'title': 'title',
'description': 'description',
'timestamp': ('firstExposureDatetime', {parse_iso8601}),
'duration': ('playTime', {int_or_none}),
'like_count': ('likeItCount', {int_or_none}),
'view_count': ('playCount', {int_or_none}),
'comment_count': ('commentCount', {int_or_none}),
'thumbnail': ('thumbnailImageUrl', {url_or_none}),
'uploader': 'channelName',
'uploader_id': 'channelId',
'uploader_url': ('channelUrl', {url_or_none}),
'age_limit': ('adultVideo', {lambda x: 19 if x else None}),
})))
return info
View on GitHub (pinned to 81ecd58b13)
Solutions
- Open the clip URL in a browser (ideally from Korea) and confirm it still plays
- Retry with --proxy using a Korean exit node - many Naver clips are KR-only
- Pass cookies if the clip requires login
- Update yt-dlp to latest nightly
- Report with --verbose if the play-info JSON shape changed
Defensive patterns
Strategy: try-catch
Validate before calling
import json, urllib.request
def naver_clip_extractable(video_id) -> bool:
api = f'https://tv.naver.com/api/clips/{video_id}/play-info'
with urllib.request.urlopen(api) as r:
data = json.load(r)
return bool(data.get('clip', {}).get('videoId') and data.get('play', {}).get('inKey')) Type guard
def play_info_complete(data: dict) -> bool:
return bool(data.get('clip', {}).get('videoId')) and bool(data.get('play', {}).get('inKey')) Try / catch
from yt_dlp.utils import ExtractorError
try:
info = ydl.extract_info(url, download=False)
except ExtractorError as e:
if 'Unable to extract video info' in str(e):
# missing videoId/inKey: deleted, private, or region-locked clip
mark_unavailable(url) Prevention
- Pre-check the play-info API for videoId/inKey before queueing Naver clips
- Use Korean exit proxies for NaverTV jobs; many clips are KR-only
- Distinguish 'field missing' (permanent) from network errors (transient) in your retry logic
When it happens
Trigger: _call_api('/clips/<video_id>/play-info') returns JSON where traverse_obj of ('clip','videoId') or ('play','inKey') comes back empty: clip deleted or privated, region-locked content (Naver frequently restricts to KR), or a changed API schema.
Common situations: Clip removed/made private; accessing NaverTV from outside Korea or from datacenter IPs; Naver API changes after site updates; clips that only play in the mobile app.
Related errors
- Mediasite says: {}
- Unable to resolve redirect URL
- Stream is offline.
- Unknown status {status!r}
- Unexpected content type {content_type!r}
AI-assisted analysis of yt-dlp/yt-dlp@81ecd58b13 (2026-08-22).
Data as JSON: /api/errors/d2aa3cb0992641ad.
Report an issue: GitHub.