ytdl-org/youtube-dl · error · ExtractorError

data['message']

Error message

data['message']

What it means

Raised by the Flickr extractor's _call_api helper when the Flickr API response has stat != 'ok'; the response's own 'message' field is re-raised as the error. This is Flickr's server-side rejection of the API call (photos.getInfo or photos.getSizes), typically for nonexistent/private photos or a bad api_key.

Source

Thrown at youtube_dl/extractor/flickr.py:65

        '7': 'No known copyright restrictions',
        '8': 'United States government work',
        '9': 'Public Domain Dedication (CC0)',
        '10': 'Public Domain Work',
    }

    def _call_api(self, method, video_id, api_key, note, secret=None):
        query = {
            'photo_id': video_id,
            'method': 'flickr.%s' % method,
            'api_key': api_key,
            'format': 'json',
            'nojsoncallback': 1,
        }
        if secret:
            query['secret'] = secret
        data = self._download_json(self._API_BASE_URL + compat_urllib_parse_urlencode(query), video_id, note)
        if data['stat'] != 'ok':
            raise ExtractorError(data['message'])
        return data

    def _real_extract(self, url):
        video_id = self._match_id(url)

        api_key = self._download_json(
            'https://www.flickr.com/hermes_error_beacon.gne', video_id,
            'Downloading api key')['site_key']

        video_info = self._call_api(
            'photos.getInfo', video_id, api_key, 'Downloading video info')['photo']
        if video_info['media'] == 'video':
            streams = self._call_api(
                'video.getStreamInfo', video_id, api_key,
                'Downloading streams info', video_info['secret'])['streams']

            preference = qualities(
                ['288p', 'iphone_wifi', '100', '300', '700', '360p', 'appletv', '720p', '1080p', 'orig'])

View on GitHub (pinned to 956b8c5855)

Solutions

  1. Open the Flickr photo page in a browser to confirm it is public and is a valid photo id
  2. Update youtube-dl/yt-dlp so the api_key bootstrap (site_key from the beacon endpoint) matches Flickr's current page
  3. If the photo is private, log in and supply cookies, or use an authorized API flow
  4. Check the message text: 'Photo not found' means bad id; permission errors mean access, not a bug

Example fix

# before
youtube_dl 'https://www.flickr.com/photos/user/12345678901'
# ERROR: Photo not found

# after
yt-dlp 'https://www.flickr.com/photos/user/76543210987'  # existing public photo
Defensive patterns

Strategy: validation

Validate before calling

# Validate the photo exists and is a video before invoking the extractor
import json, urllib.request
resp = json.load(urllib.request.urlopen(api_url))
if resp.get('stat') != 'ok':
    handle_rejection(resp.get('message'))

Try / catch

try:
    info = ydl.extract_info(url)
except ExtractorError as e:
    if 'Photo not found' in str(e) or 'permission' in str(e).lower():
        mark_invalid(url)

Prevention

When it happens

Trigger: _download_json of self._API_BASE_URL + query returns JSON with stat other than 'ok', then 'raise ExtractorError(data["message"])' runs. Common triggers: photo_id does not exist or was deleted, the photo is private, or the site_key scraped from hermes_error_beacon.gne no longer authorizes API calls.

Common situations: Following stale Flickr photo links; extracting photos whose owner flipped them to private; Flickr rotating the public API key embedded in the page after an extractor release.

Related errors


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