ytdl-org/youtube-dl · error · ExtractorError

%s is not a video or animated image

Error message

%s is not a video or animated image

What it means

Raised by ImgurIE when the post's API metadata shows it is neither a video nor an animated image - the 'type' is not 'video' and 'metadata'.'is_animated' is falsy. It is an expected error telling the user the imgur ID points at a static picture, which youtube-dl cannot download as media.

Source

Thrown at youtube_dl/extractor/imgur.py:104

                         for v in ('width', 'height'))
        return [{
            'format_id': tw_id,
            'url': tw_stream,
            'ext': ext or determine_ext(tw_stream),
            'width': width,
            'height': height,
        }]

    def _real_extract(self, url):
        video_id = self._match_id(url)
        data = self._call_api('media', video_id, fatal=False, expected_status=404)
        webpage = self._download_webpage(
            'https://i.imgur.com/{id}.gifv'.format(id=video_id), video_id, fatal=not data) or ''

        if not traverse_obj(data, ('media', 0, (
                ('type', T(lambda t: t == 'video' or None)),
                ('metadata', 'is_animated'))), get_all=False):
            raise ExtractorError(
                '%s is not a video or animated image' % video_id,
                expected=True)

        media_fmt = traverse_obj(data, ('media', 0, {
            'url': ('url', T(url_or_none)),
            'ext': 'ext',
            'width': ('width', T(int_or_none)),
            'height': ('height', T(int_or_none)),
            'filesize': ('size', T(int_or_none)),
            'acodec': ('metadata', 'has_sound', T(lambda b: None if b else 'none')),
        }))

        media_url = traverse_obj(media_fmt, 'url')
        if media_url:
            if not media_fmt.get('ext'):
                media_fmt['ext'] = mimetype2ext(traverse_obj(
                    data, ('media', 0, 'mime_type'))) or determine_ext(media_url)
            if traverse_obj(data, ('media', 0, 'type')) == 'image':

View on GitHub (pinned to 956b8c5855)

Solutions

  1. Confirm the link is actually a GIF or video in a browser; if it is static, download the image with a plain HTTP client instead.
  2. Use the direct media URL (i.imgur.com/<id>.gifv/.mp4) for animated content.
  3. Check the ID for typos/truncation.

Example fix

// before
youtube_dl 'https://imgur.com/abc123'   # static photo
# => ERROR: abc123 is not a video or animated image

// after
# fetch the image directly
curl -O 'https://i.imgur.com/abc123.jpg'
Defensive patterns

Strategy: validation

Validate before calling

import requests
data = requests.get(f'https://api.imgur.com/v3/media/{imgur_id}', headers={'Authorization': f'Client-ID {client_id}'}, timeout=10).json()
media = data.get('media', [{}])[0]
if media.get('type') != 'video' and not media.get('metadata', {}).get('is_animated'):
    skip('static image')

Type guard

def is_imgur_video(media_entry: dict) -> bool:
    return bool(media_entry) and (
        media_entry.get('type') == 'video'
        or bool(media_entry.get('metadata', {}).get('is_animated'))
    )

Try / catch

try:
    ydl.extract_info(imgur_url)
except ExtractorError as e:
    if 'is not a video or animated image' in str(e):
        download_as_static_image(imgur_url)

Prevention

When it happens

Trigger: Passing an imgur gallery/image URL (https://imgur.com/<id>) whose media entry is a plain JPEG/PNG; the check on ('media', 0, type/is_animated) fails.

Common situations: Users copy links to memes/photos on Imgur, or the URL's ID was truncated; also posts that were converted from GIF to static images.

Related errors


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