ytdl-org/youtube-dl · error · ExtractorError
%s (site code %d)
Error message
%s (site code %d)
What it means
Raised by NetEase Music's format builder when no playable media links were produced AND the returned error code is outside 200-399 — i.e. the site API explicitly errored. The message embeds the numeric site code (e.g. lack of permission or copyright block). For codes inside 200-399 it instead raises a geo-restriction error limited to CN.
Source
Thrown at youtube_dl/extractor/neteasemusic.py:143
song_url = try_get(song, lambda x: x['url'])
if not song_url:
continue
if self._is_valid_url(song_url, info['id'], 'song'):
formats.append({
'url': song_url,
'ext': details.get('extension'),
'abr': float_or_none(song.get('br'), scale=1000),
'format_id': song_format,
'filesize': int_or_none(song.get('size')),
'asr': int_or_none(details.get('sr')),
})
elif err == 0:
err = try_get(song, lambda x: x['code'], int)
if not formats:
msg = 'No media links found'
if err != 0 and (err < 200 or err >= 400):
raise ExtractorError(
'%s (site code %d)' % (msg, err, ), expected=True)
else:
self.raise_geo_restricted(
msg + ': probably this video is not available from your location due to geo restriction.',
countries=['CN'])
return formats
@classmethod
def convert_milliseconds(cls, ms):
return int(round(ms / 1000.0))
def query_api(self, endpoint, video_id, note):
req = sanitized_Request('%s%s' % (self._API_BASE, endpoint))
req.add_header('Referer', self._API_BASE)
return self._download_json(req, video_id, note)
View on GitHub (pinned to 956b8c5855)
Solutions
- If the code indicates regional unavailability, retry through a mainland-China proxy: --proxy <cn-proxy>.
- Look up the numeric site code in NetEase API references to see if it is copyright/login related; if login-gated, pass cookies with --cookies.
- Update youtube-dl / yt-dlp if all songs fail uniformly (API change rather than per-song block).
Example fix
# before youtube-dl 'http://music.163.com/song?id=123456' # after youtube-dl --proxy http://cn-proxy:8080 'http://music.163.com/song?id=123456'
Defensive patterns
Strategy: retry
Validate before calling
import requests
r = requests.get('http://music.163.com/api/song/detail', params={'id': song_id}).json()
if not r.get('songs'):
print('song unavailable — check region/licensing before extracting') Try / catch
from youtube_dl.utils import ExtractorError, GeoRestrictedError
try:
ydl.extract_info(url)
except GeoRestrictedError:
retry_with_proxy(url, region='CN')
except ExtractorError as e:
if 'site code' in str(e):
code = int(str(e).rsplit(' ', 1)[-1].rstrip(')'))
handle_netease_code(code) # e.g. login-gated vs removed
else:
raise Prevention
- Route NetEase requests via CN egress when catalog access is region-checked.
- Map the numeric site code before retrying — only region codes benefit from a proxy.
- Pass cookies for licensed tracks tied to an account.
When it happens
Trigger: Calling NetEaseCloudMusicIE on a song whose API response yields no formats and err (from the per-format 'code' or song['code']) is non-zero and not in [200,400).
Common situations: Region-locked NetEase catalog entries; songs removed for licensing; the 200-399 branch (e.g. -110 or in-range codes) usually means 'not available from your location', fixed by CN egress.
Related errors
- This song is blocked in this region
- This video is not available from your country.
- %s said: video is not available
- %s returned error: %s - %s
- %s: No songs found, try using proxy
AI-assisted analysis of ytdl-org/youtube-dl@956b8c5855 (2026-08-14).
Data as JSON: /api/errors/25758c4b8f2f45bb.
Report an issue: GitHub.