youtube-transcript-api errors
VideoUnavailable, InvalidVideoId and VideoUnplayable in youtube-transcript-api
What youtube-transcript-api means by an unavailable, invalid or unplayable video, and how to tell a wrong ID from a private, deleted or members-only video.
Running this on a server? TranscriptFetch returns the same transcript from any IP, no proxies. Try it free →
Three errors with one question behind them: will YouTube play this video to an anonymous visitor? The library raises one of them when the answer is no.
The errors
| Exception | Raised when (version 1.2.4) |
|---|---|
InvalidVideoId | YouTube says the video is unavailable and what you passed starts with http |
VideoUnavailable | YouTube says "This video is unavailable": a wrong ID, a deleted video or a private one |
VideoUnplayable | YouTube refuses for any other reason, which the message quotes |
Their messages:
InvalidVideoId: You provided an invalid video id. Make sure you are using the video id and NOT the url!
VideoUnavailable: The video is no longer available
VideoUnplayable: The video is unplayable for the following reason: ...A real VideoUnplayable, from a members-only video:
youtube_transcript_api._errors.VideoUnplayable:
Could not retrieve a transcript for the video https://www.youtube.com/watch?v=VIDEO_ID! This is most likely caused by:
The video is unplayable for the following reason: Join this channel to get access to members-only content like this video, and other exclusive perks.InvalidVideoId: pass the ID, not the URL
fetch() takes the 11-character ID, not a link. This helper pulls the ID out of the common link shapes:
import re
from urllib.parse import parse_qs, urlparse
def video_id(link: str) -> str:
u = urlparse(link if "//" in link else "https://" + link)
if u.hostname in ("youtu.be", "www.youtu.be"):
return u.path.lstrip("/")[:11]
if "v" in parse_qs(u.query):
return parse_qs(u.query)["v"][0][:11]
m = re.search(r"/(?:shorts|live|embed)/([\w-]{11})", u.path)
if m:
return m.group(1)
raise ValueError(f"no video ID in {link}")
video_id("https://youtu.be/dQw4w9WgXcQ?si=abc") # 'dQw4w9WgXcQ'
video_id("https://m.youtube.com/watch?v=dQw4w9WgXcQ&t=1") # 'dQw4w9WgXcQ'
video_id("https://www.youtube.com/shorts/dQw4w9WgXcQ") # 'dQw4w9WgXcQ'VideoUnavailable: check the ID, then the video
- IDs are 11 characters and case-sensitive. A trimmed or mistyped ID looks exactly like a deleted video.
- Open the video in a signed-out browser window. If YouTube says it is unavailable there too, it was removed or made private, and nothing can fetch it.
VideoUnplayable: read the reason
The message quotes YouTube's own reason:
- Members-only ("Join this channel…"): only channel members can play it.
- Region locked: the video is blocked in your server's country. A proxy in an allowed country can help; the library's
WebshareProxyConfigtakesfilter_ip_locations=["us"]to pick one. - Not available yet: a scheduled premiere or live stream has no transcript until it has aired.
Skipping them cleanly
from youtube_transcript_api import (
InvalidVideoId,
VideoUnavailable,
VideoUnplayable,
YouTubeTranscriptApi,
)
try:
transcript = YouTubeTranscriptApi().fetch(video_id)
except InvalidVideoId:
... # a URL slipped through: extract the ID first
except (VideoUnavailable, VideoUnplayable):
... # deleted, private, members-only or region locked: skip itWith TranscriptFetch
TranscriptFetch (our product) takes the link in any of these shapes, with tracking parameters and all, so there is no ID to extract. It cannot open private, deleted or members-only videos either: those come back as a clear error code (private, members_only) and failed requests are free.
FAQ
Are video IDs case-sensitive?
Yes. dQw4w9WgXcQ and dqw4w9wgxcq are different videos, or no video at all.
The link works in my browser, so why is it unavailable?
Your browser is probably signed in. Private, members-only and age-restricted videos play for a signed-in account that has access and for nobody else. Try the link in a signed-out window.
Need transcripts that work from a server?
TranscriptFetch fetches YouTube, TikTok and Instagram transcripts from its own network, with AI transcription when a video has no captions. Free credits every month, no card.