ytdl-org/youtube-dl · error · ExtractorError
Video %s is not available
Error message
Video %s is not available
What it means
SpankBangIE downloads the /video page (rewritten from /embed, with a country=US cookie) and greps for an element whose id or class starts with 'video_removed'. A match means the clip was taken down, so it raises 'Video <id> is not available' as an expected error before format parsing.
Source
Thrown at youtube_dl/extractor/spankbang.py:80
'url': 'https://m.spankbang.com/3vvn/play',
'only_matching': True,
}, {
'url': 'https://spankbang.com/2y3td/embed/',
'only_matching': True,
}, {
'url': 'https://spankbang.com/2v7ik-7ecbgu/playlist/latina+booty',
'only_matching': True,
}]
def _real_extract(self, url):
mobj = re.match(self._VALID_URL, url)
video_id = mobj.group('id') or mobj.group('id_2')
webpage = self._download_webpage(
url.replace('/%s/embed' % video_id, '/%s/video' % video_id),
video_id, headers={'Cookie': 'country=US'})
if re.search(r'<[^>]+\b(?:id|class)=["\']video_removed', webpage):
raise ExtractorError(
'Video %s is not available' % video_id, expected=True)
formats = []
def extract_format(format_id, format_url):
f_url = url_or_none(format_url)
if not f_url:
return
f = parse_resolution(format_id)
ext = determine_ext(f_url)
if format_id.startswith('m3u8') or ext == 'm3u8':
formats.extend(self._extract_m3u8_formats(
f_url, video_id, 'mp4', entry_protocol='m3u8_native',
m3u8_id='hls', fatal=False))
elif format_id.startswith('mpd') or ext == 'mpd':
formats.extend(self._extract_mpd_formats(
f_url, video_id, mpd_id='dash', fatal=False))
elif ext == 'mp4' or f.get('width') or f.get('height'):View on GitHub (pinned to 956b8c5855)
Solutions
- Open the URL in a browser (from the same region) to read the exact removal notice.
- Search the site for re-uploads under a different id.
- If the notice says region-restricted, a VPN to the allowed region may make it extractable.
- Verify the URL slug - truncated ids land on removal-style pages.
Defensive patterns
Strategy: try-catch
Validate before calling
webpage = requests.get(rewritten_video_url, headers={'Cookie': 'country=US'}).text
if re.search(r'<[^>]+\b(?:id|class)=["\']video_removed', webpage):
skip(video_id) Type guard
def video_was_removed(webpage: str) -> bool:
return bool(re.search(r'<[^>]+\b(?:id|class)=["\']video_removed', webpage)) Try / catch
try:
extract(url)
except ExtractorError as e:
if 'is not available' in str(e):
drop_from_queue(video_id)
else:
raise Prevention
- Note the extractor forces country=US; region-removed clips need matching egress.
- Remove dead ids from playlists; takedowns are frequent and permanent.
- Verify slugs are complete when copying URLs.
When it happens
Trigger: Extracting a spankbang.com URL whose page contains e.g. <div class="video_removed"> - i.e. removed for DMCA/terms, deleted by the uploader, or region-swapped content that the US-cookie route cannot see. The state-specific variants (removed in your region, by uploader, etc.) all match this check.
Common situations: DMCA takedowns (very frequent on this site); uploader deletions; clips removed for US viewers specifically - the extractor forces country=US, so content legal only elsewhere always looks removed; mistyped slug.
Related errors
- Gfycat said: %s
- Did not get a media key
- Video %s is no longer available
- %s returned error: %s
- Video %s does not exist
AI-assisted analysis of ytdl-org/youtube-dl@956b8c5855 (2026-08-14).
Data as JSON: /api/errors/6038cdf82f086683.
Report an issue: GitHub.