yt-dlp/yt-dlp · error · DownloadError

Unable to download video subtitles for {sub_lang!r}: {err}

Error message

Unable to download video subtitles for {sub_lang!r}: {err}

What it means

Raised by YoutubeDL._download_subtitle when the actual subtitle file download (self.dl on the subtitle URL) fails with DownloadError, ExtractorError, OSError, ValueError, or any network exception. The message embeds the language code (e.g. 'en') and the underlying error text. Behavior depends on 'ignoreerrors': when False, report_error() prints it and a DownloadError is raised (aborting the video); when 'only_download', DownloadError is raised for the caller to catch; when True, it degrades to a warning and processing continues.

Source

Thrown at yt_dlp/YoutubeDL.py:4501

                    sub_info['filepath'] = sub_filename
                    ret.append((sub_filename, sub_filename_final))
                    continue
                except OSError:
                    self.report_error(f'Cannot write video subtitles file {sub_filename}')
                    return None

            try:
                sub_copy = sub_info.copy()
                sub_copy.setdefault('http_headers', info_dict.get('http_headers'))
                self.dl(sub_filename, sub_copy, subtitle=True)
                sub_info['filepath'] = sub_filename
                ret.append((sub_filename, sub_filename_final))
            except (DownloadError, ExtractorError, OSError, ValueError, *network_exceptions) as err:
                msg = f'Unable to download video subtitles for {sub_lang!r}: {err}'
                if self.params.get('ignoreerrors') is not True:  # False or 'only_download'
                    if not self.params.get('ignoreerrors'):
                        self.report_error(msg)
                    raise DownloadError(msg)
                self.report_warning(msg)
        return ret

    def _write_thumbnails(self, label, info_dict, filename, thumb_filename_base=None):
        """ Write thumbnails to file and return list of (thumb_filename, final_thumb_filename); or None if error """
        write_all = self.params.get('write_all_thumbnails', False)
        thumbnails, ret = [], []
        if write_all or self.params.get('writethumbnail', False):
            thumbnails = info_dict.get('thumbnails') or []
            if not thumbnails:
                self.to_screen(f'[info] There are no {label} thumbnails to download')
                return ret
        multiple = write_all and len(thumbnails) > 1

        if thumb_filename_base is None:
            thumb_filename_base = filename
        if thumbnails and not thumb_filename_base:
            self.write_debug(f'Skipping writing {label} thumbnail')

View on GitHub (pinned to 81ecd58b13)

Solutions

  1. Read the wrapped {err} text — it names the real cause (HTTP 404, timeout, etc.) and that is what must be fixed.
  2. If missing subs are acceptable, set 'ignoreerrors': True (CLI: --ignore-errors) so the failure becomes a warning and the batch continues.
  3. Verify the language actually exists in info_dict['subtitles'] / info_dict['automatic_captions'] before enabling subtitle download for that code.
  4. For authentication-dependent subtitles, pass cookies via 'cookiefile' so the subtitle request is authorized.
  5. Retry later if the subtitle URL was extracted long before download (URL expiry).

Example fix

# before
ydl_opts = {'writesubtitles': True, 'subtitleslangs': ['en']}
# after: tolerate missing subs so the rest of the batch survives
ydl_opts = {'writesubtitles': True, 'subtitleslangs': ['en'], 'ignoreerrors': True}
Defensive patterns

Strategy: try-catch

Try / catch

from yt_dlp import YoutubeDL
from yt_dlp.utils import DownloadError

with YoutubeDL(opts) as ydl:
    try:
        ydl.download([url])
    except DownloadError as err:
        if 'Unable to download video subtitles' in str(err):
            log.warning('subtitles unavailable for %s: %s', url, err)  # continue batch
        else:
            raise

Prevention

When it happens

Trigger: Running ydl.download()/ydl.extract_info() with writesubtitles/writeautomaticsub and subtitleslangs set, where the subtitle URL returns 404/403, the extractor published a stale subtitle URL, a connection error occurs, or the sub_info dict is malformed (ValueError). Also hit when a subtitle format requires headers/cookies not forwarded from info_dict['http_headers'].

Common situations: Batch downloads with --write-subs where one video's subtitle track is missing or geo-blocked; YouTube auto-caption URLs expiring before download; subtitles listed by the extractor but later removed; corporate proxies causing network_exceptions.

Related errors


AI-assisted analysis of yt-dlp/yt-dlp@81ecd58b13 (2026-08-22). Data as JSON: /api/errors/2eec7c6ba45f3c3e. Report an issue: GitHub.