ytdl-org/youtube-dl · error · ExtractorError
Youku server reported error %i[: error_note]
Error message
Youku server reported error %i[: error_note]
What it means
YoukuIE raises this catch-all when the UPS get.json response has an error object whose note matches neither the geo-blocked ('因版权原因无法观看此视频') nor the private ('该视频被设为私密') pattern. The message interpolates the numeric error code and the raw server note, so it relays whatever upstream error Youku returned. It is not marked expected=True, so youtube-dl treats it as a generic extraction failure.
Source
Thrown at youtube_dl/extractor/youku.py:189
data = self._download_json(
'https://ups.youku.com/ups/get.json', video_id,
'Downloading JSON metadata',
query=basic_data_params, headers=headers)['data']
error = data.get('error')
if error:
error_note = error.get('note')
if error_note is not None and '因版权原因无法观看此视频' in error_note:
raise ExtractorError(
'Youku said: Sorry, this video is available in China only', expected=True)
elif error_note and '该视频被设为私密' in error_note:
raise ExtractorError(
'Youku said: Sorry, this video is private', expected=True)
else:
msg = 'Youku server reported error %i' % error.get('code')
if error_note is not None:
msg += ': ' + error_note
raise ExtractorError(msg)
# get video title
video_data = data['video']
title = video_data['title']
formats = [{
'url': stream['m3u8_url'],
'format_id': self.get_format_name(stream.get('stream_type')),
'ext': 'mp4',
'protocol': 'm3u8_native',
'filesize': int(stream.get('size')),
'width': stream.get('width'),
'height': stream.get('height'),
} for stream in data['stream'] if stream.get('channel_type') != 'tail']
self._sort_formats(formats)
return {
'id': video_id,View on GitHub (pinned to 956b8c5855)
Solutions
- Read the code and note in the message — they identify the real upstream reason (e.g. -6 typically means the video is unavailable); act on that reason (different video, login-required content, etc.).
- Reproduce the request to ups.youku.com with the same query params in a browser/curl and inspect data.error to confirm what Youku now returns.
- If the note text for a known case changed, add/adjust the substring match in the if/elif chain in youku.py so it maps to the friendly expected=True message.
- If params/headers are stale, compare with the current Youku web player request (referer, ctoken, cck, ua) and update basic_data_params/headers.
Example fix
// before
msg = 'Youku server reported error %i' % error.get('code')
if error_note is not None:
msg += ': ' + error_note
raise ExtractorError(msg)
// after (treat a new known note as expected)
msg = 'Youku server reported error %i' % error.get('code')
if error_note is not None:
msg += ': ' + error_note
raise ExtractorError(msg, expected=True) # if the note is a user-content issue, not a bug Defensive patterns
Strategy: try-catch
Validate before calling
import json, urllib.request
def youku_error_note(video_id, params):
url = 'https://ups.youku.com/ups/get.json?' + urllib.parse.urlencode(params)
with urllib.request.urlopen(url) as r:
data = json.load(r).get('data', {})
return data.get('error') # None means extractable; else inspect code/note Type guard
def is_known_youku_error(err) -> bool:
"""True when the message is a known user-content condition, not a bug."""
msg = str(err)
return ('China only' in msg) or ('private' in msg) or msg.startswith('Youku server reported error') Try / catch
try:
info = ydl.extract_info(url)
except ExtractorError as e:
if str(e).startswith('Youku server reported error'):
code = parse_code(str(e)) # log code/note and triage per upstream reason
handle_upstream(code)
else:
raise Prevention
- Log the numeric code and note verbatim; they are the upstream source of truth.
- Pin an extractor version known to work with the current Youku API and monitor for note-text drift.
When it happens
Trigger: Any call to https://ups.youku.com/ups/get.json that returns data.error with a code/note outside the two known patterns: deleted videos, region blocks with different wording, expired links, anti-crawler/rate-limit responses, or API changes that shift note text.
Common situations: Deleted or taken-down videos; Youku A/B wording changes in the error note; ccb params or headers (basic_data_params/headers) becoming stale after an API revision so the server rejects the request; running from datacenter IPs that Youku throttles.
Related errors
- Youku said: Sorry, this video is available in China only
- Youku said: Sorry, this video is private
- item['msg'] (dynamic server message, e.g. 'Sorry, this conte
- Invalid path
- Unauthorized user "%s"
AI-assisted analysis of ytdl-org/youtube-dl@956b8c5855 (2026-08-14).
Data as JSON: /api/errors/8c0fc1ad8c6491a7.
Report an issue: GitHub.