ytdl-org/youtube-dl · error · ExtractorError

couldn't extract vid and key

Error message

couldn't extract vid and key

What it means

Raised by Naver's extractor when the page's playerInfoJson.currentClip lacks videoId ('vid') or inKey ('in_key') — the two tokens required to call the video info API. Before raising, it distinguishes auth == 'notCountry' (geo-restricted to KR) and 'notLogin' (login required) via dedicated raises; this generic error fires only when neither applies. It is not expected=True.

Source

Thrown at youtube_dl/extractor/naver.py:157

    def _real_extract(self, url):
        video_id = self._match_id(url)
        content = self._download_json(
            'https://tv.naver.com/api/json/v/' + video_id,
            video_id, headers=self.geo_verification_headers())
        player_info_json = content.get('playerInfoJson') or {}
        current_clip = player_info_json.get('currentClip') or {}

        vid = current_clip.get('videoId')
        in_key = current_clip.get('inKey')

        if not vid or not in_key:
            player_auth = try_get(player_info_json, lambda x: x['playerOption']['auth'])
            if player_auth == 'notCountry':
                self.raise_geo_restricted(countries=['KR'])
            elif player_auth == 'notLogin':
                self.raise_login_required()
            raise ExtractorError('couldn\'t extract vid and key')
        info = self._extract_video_info(video_id, vid, in_key)
        info.update({
            'description': clean_html(current_clip.get('description')),
            'timestamp': int_or_none(current_clip.get('firstExposureTime'), 1000),
            'duration': parse_duration(current_clip.get('displayPlayTime')),
            'like_count': int_or_none(current_clip.get('recommendPoint')),
            'age_limit': 19 if current_clip.get('adult') else None,
        })
        return info

View on GitHub (pinned to 956b8c5855)

Solutions

  1. Update youtube-dl / yt-dlp first — key drift in playerInfoJson is a recurring Naver pattern.
  2. If prompted for login elsewhere, pass cookies: --cookies-from-browser or --cookies <file> so authenticated clips expose vid/inKey.
  3. If the failure came before any auth hint, confirm the clip plays anonymously in a browser from your region; if it needs KR egress, use a KR proxy.

Example fix

# before
youtube-dl https://tv.naver.com/v/12345678

# after
youtube-dl --cookies-from-browser chrome https://tv.naver.com/v/12345678
Defensive patterns

Strategy: try-catch

Validate before calling

import requests
clip = (requests.get(url).json().get('playerInfoJson') or {}).get('currentClip') or {}
if not clip.get('videoId') or not clip.get('inKey'):
    auth = (requests.get(url).json().get('playerInfoJson') or {}).get('playerOption', {}).get('auth')
    print('blocked:', auth or 'unknown/extraction drift')

Try / catch

from youtube_dl.utils import ExtractorError, GeoRestrictedError
try:
    ydl.extract_info(url)
except GeoRestrictedError:
    retry_with_proxy(url, region='KR')
except ExtractorError as e:
    if 'raise_login_required' in str(e) or 'login' in str(e).lower():
        retry_with_cookies(url)
    elif "couldn't extract vid and key" in str(e):
        update_or_report(url)  # playerInfoJson shape changed
    else:
        raise

Prevention

When it happens

Trigger: currentClip.get('videoId') or currentClip.get('inKey') returns None/empty on a Naver TV/V-LIVE clip page whose playerOption.auth is neither 'notCountry' nor 'notLogin'.

Common situations: Naver changing its embedded playerInfoJson shape (rename/removal of keys) so the extractor misses them; clips with unusual delivery types; extractor version lag — by far the most common cause.

Related errors


AI-assisted analysis of ytdl-org/youtube-dl@956b8c5855 (2026-08-14). Data as JSON: /api/errors/ef23a3975f5c5bf7. Report an issue: GitHub.