Skip to content

yt-dlp downloads get zero retries because ydl_opts omits the retry keys #262

Description

@ReemX

Summary

ytdlp_downloader.py builds ydl_opts without retries, extractor_retries or fragment_retries. Through yt-dlp's Python API that means zero retries, because RetryManager.__init__ does:

self.retries = _retries or 0

An unset key arrives as None, and None or 0 is 0. The CLI does not have this problem because options.py sets default=10 for --retries and default=3 for --extractor-retries. Those defaults live in the argument parser, so nothing applies them when the library is driven directly.

Demonstrated without touching the network:

Transmute (key unset -> None)    retries=0   total_attempts=1
CLI default --retries 10         retries=10  total_attempts=11

So a single transient HTTP 403 from YouTube, which yt-dlp would normally ride out, ends the download immediately.

Second half of the problem

"ignoreerrors": True means the per-entry failure never raises. extract_info returns with the entry as None, it gets filtered out here:

entries = [entry for entry in (raw_entries or []) if entry]

if not entries:
    shutil.rmtree(staging_dir, ignore_errors=True)
    raise DownloadError("yt-dlp completed but no files were downloaded")

and the caller answers 422. The real cause, ERROR: unable to download video data: HTTP Error 403: Forbidden, is printed by yt-dlp but never reaches the API response or the UI. From the user side a retryable network blip is indistinguishable from an unsupported URL.

Suggested fix

Two small changes in ydl_opts:

"retries": 10,
"extractor_retries": 3,
"fragment_retries": 10,

and capturing the yt-dlp error so the message can be surfaced instead of the generic "no files were downloaded". A logger hook or dropping ignoreerrors for the single-video case would both work, though ignoreerrors is clearly there on purpose for playlists, so the single-entry path is probably where to special case it.

On effect size, which I did not manage to measure

Being upfront about the limits of what I checked. I could not put a number on how much the retry setting helps in practice.

I hit this while YouTube was returning intermittent 403s. On the stock image at that point, success was about 42 percent across two different videos, so it was not specific to one video. By the time I ran the retries=0 against retries=10 comparison the condition had cleared, and both configurations scored 8 out of 8. With nothing failing there is nothing for a retry to recover, so the two are indistinguishable in that data.

Some of that intermittency was likely self inflicted, since I had pulled a fair number of test downloads from one address by then. Manufacturing another bad window to get a cleaner number did not seem like a reasonable thing to do to your upstream.

So treat the retry count as a code reading finding rather than a measured improvement. Making one attempt where yt-dlp's own CLI makes eleven looks wrong on its face, and the swallowed error message is worth fixing regardless of how often the underlying failure happens.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions