jamin labs

YouTube channel RSS feed returns 404 for a channel that exists

Field note · Last tested Oct 12, 2026 · Jamin Kim

The short answer

On 2026-10-12 YouTube's channel RSS feed (feeds/videos.xml) answered 404 Not Found, and sometimes 500, for channels that plainly existed. It lasted about 8 hours and then fixed itself. My research bot read each 404 as "this channel is gone", skipped it, and quietly collected about half the usual videos.

The fix is on my side. I now count any non-200 answer as a failure, retry only the failed channels after a pause, and fail the run loudly when too many feeds stay unread. If the daily video count suddenly halves, the feed is the first thing I check.

What the feed answered

GET https://www.youtube.com/feeds/videos.xml?channel_id=UC…  → 404 Not Found
GET https://www.youtube.com/feeds/videos.xml?channel_id=UC…  → 500
(the same channel switched between 404 and 500 from one request to the next)

Channels that had videos: 30 · answered 200: 1
YouTube's own official channel feed: 404 Not Found

Where I hit it

What reads the feeds
A research bot (Python, standard library only) that collects yesterday's videos from YouTube channel RSS feeds
Feed URL
https://www.youtube.com/feeds/videos.xml?channel_id=UC…
When
2026-10-12, from about 08:15 to 16:09 (about 8 hours)
Channels that morning
30 channels that had videos; 1 answered 200
Second machine
A second server reading 15 channels: all 15 answered 404

Why it happens

My collector treated a 404 as "channel deleted" and moved on. A deleted channel has no feed, so that looked reasonable. That morning, though, the 404s came from channels that were posting normally. The report had about half the videos it usually has, and the failure count showed only 53, because the skipped channels were never counted as failures.

The channel ids and my network were probably fine (this part is inference). Of 30 channels that had videos, 1 got a 200. The same channel flipped between 404 and 500 from one request to the next, YouTube's own official channel feed returned 404 too, and a second server reading 15 channels got 404 for all 15. That points to the feed endpoint on YouTube's side. I couldn't find any explanation from YouTube.

Other people have hit the same thing. A Google developer forum thread collects reports of 404s on this endpoint for active channels, including February 2026. A GitHub issue from October 2026 describes a scheduled job failing on the same 404, once on a 500. Feeder's help page on YouTube feeds says the feed server sometimes answers every feed with 404 for hours at a time.

The fix

  1. Treat every non-200 answer as a failure. A 404 from this endpoint does not prove the channel is gone, so return nothing and let the caller count it.
    import http.client
    import urllib.request
    
    FEED = "https://www.youtube.com/feeds/videos.xml?channel_id={}"
    
    def fetch(channel_id):
        """Feed XML, or None if the request failed for any reason.
        A 404 here is a failure to retry, not proof that the channel was deleted."""
        try:
            with urllib.request.urlopen(FEED.format(channel_id), timeout=20) as r:
                return r.read()
        except (OSError, http.client.HTTPException):  # HTTPError (404, 500 ...), timeouts, cut-off reads
            return None
  2. Keep the failed channel ids and fetch only those again after a pause. I wait 30 seconds, then 2 minutes, then 5 minutes. Channels that still fail are reported as failed, never dropped.
    import time
    
    RETRY_WAITS = (30, 120, 300)  # seconds
    
    def scan(channel_ids):
        feeds, todo = {}, list(channel_ids)
        for wait in (0, *RETRY_WAITS):
            if not todo:
                break
            time.sleep(wait)
            failed = []
            for cid in todo:
                xml = fetch(cid)
                if xml is None:
                    failed.append(cid)
                else:
                    feeds[cid] = xml
            todo = failed
        return feeds, todo  # todo now holds the channels that never answered
  3. Fail the run when too many feeds are still unread. If more than 20% fail, my collector ends the run as failed and its timer tries again 8 minutes later, up to 4 times in 2 hours. After the cutoff (08:25 for the 08:15 run) it publishes what it has, with a partial-report warning at the top, because the feed can stay down for hours and waiting could mean no report at all.
    MAX_FAIL_SHARE = 0.2  # more than 20% unread = a bad run
    
    feeds, failed = scan(channel_ids)
    if len(failed) > MAX_FAIL_SHARE * len(channel_ids):
        if before_cutoff():
            raise RuntimeError(f"{len(failed)}/{len(channel_ids)} channel feeds failed")  # the timer runs it again
        report.warning = f"Partial report: {len(failed)} channel feeds could not be read"
  4. Watch the daily total as well. Half the usual count was the only visible sign that day, so a sudden halving should send you to the feed before anything else. My collector relies on the failed-share check above; this one line is the extra check I'd add to any feed reader.
    if today_count < usual_count / 2:
        alert(f"Only {today_count} videos today (usual: {usual_count}). Check the YouTube feeds first.")

How I checked it worked

  • The feeds came back on their own at 16:09, about 8 hours after the first failures that morning. Nothing on my side changed.
  • The collector's offline tests cover the fix: a 404 counts as a failure, only failed channels are fetched again, and a run where most feeds fail either errors out (before the cutoff) or produces a report marked partial.
  • When any channel feed fails, the morning report now says how many, so a bad feed day shows up in the report instead of as a quietly shorter list.

Sources

More field notes