ytdl-org/youtube-dl · error · ExtractorError

%s said: %s

Error message

%s said: %s

What it means

Raised by the Meta (meta.ua) extractor when the page embeds an uppod player whose decrypted 'st' configuration JSON contains a 'customnotfound' key. The uppod st blob is hex-escaped HTML entities decoded in the loop above; a customnotfound entry means the site's player itself declares the video gone. Expected=True.

Source

Thrown at youtube_dl/extractor/meta.py:52

        'only_matching': True,
    }]

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

        st_html5 = self._search_regex(
            r"st_html5\s*=\s*'#([^']+)'", webpage, 'uppod html5 st', default=None)

        if st_html5:
            # uppod st decryption algorithm is reverse engineered from function un(s) at uppod.js
            json_str = ''
            for i in range(0, len(st_html5), 3):
                json_str += '&#x0%s;' % st_html5[i:i + 3]
            uppod_data = self._parse_json(unescapeHTML(json_str), video_id)
            error = uppod_data.get('customnotfound')
            if error:
                raise ExtractorError('%s said: %s' % (self.IE_NAME, error), expected=True)

            video_url = uppod_data['file']
            info = {
                'id': video_id,
                'url': video_url,
                'title': uppod_data.get('comment') or self._og_search_title(webpage),
                'description': self._og_search_description(webpage, default=None),
                'thumbnail': uppod_data.get('poster') or self._og_search_thumbnail(webpage),
                'duration': int_or_none(self._og_search_property(
                    'video:duration', webpage, default=None)),
            }
            if 'youtube.com/' in video_url:
                info.update({
                    '_type': 'url_transparent',
                    'ie_key': 'Youtube',
                })
            return info

View on GitHub (pinned to 956b8c5855)

Solutions

  1. Open the page in a browser — the uppod player will display the same 'not found' message.
  2. Search meta.ua for the content again; deleted files have no client-side recovery.
  3. Update youtube-dl in case the uppod decryption or page structure changed, then retry with -v.
Defensive patterns

Strategy: try-catch

Type guard

def uppod_custom_notfound(uppod_data):
    return isinstance(uppod_data, dict) and bool(uppod_data.get('customnotfound'))

Try / catch

try:
    info = ydl.extract_info(url, download=False)
except ExtractorError as e:
    if 'Meta said:' in str(e):
        mark_video_removed(url)  # site's own player declared it gone
    else:
        raise

Prevention

When it happens

Trigger: Page contains st_html5 (the '#hex' uppod parameter), it decrypts to valid JSON, and that JSON has a truthy 'customnotfound' value — typically a human-readable message such as 'video not found'.

Common situations: Video deleted from meta.ua storage; regional or copyright takedown causing the player config to swap the file entry for a customnotfound message; site template changes altering the uppod parameters.

Related errors


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