yt-dlp/yt-dlp · error · ExtractorError
Unable to get available API hosts
Error message
Unable to get available API hosts
What it means
Raised by AudiusBaseIE._select_api_base: host discovery GETs https://api.audius.co/ and expects get_response_data() to yield a LIST of API host URLs to random.choice() from. If data is not a list, no _API_BASE can be set and every subsequent request is impossible.
Source
Thrown at yt_dlp/extractor/audius.py:32
response_data = response.get('data')
if response_data is not None:
return response_data
if len(response) == 1 and 'message' in response:
raise ExtractorError('API error: {}'.format(response['message']),
expected=True)
raise ExtractorError('Unexpected API response')
def _select_api_base(self):
"""Selecting one of the currently available API hosts"""
response = super()._download_json(
'https://api.audius.co/', None,
note='Requesting available API hosts',
errnote='Unable to request available API hosts')
hosts = self._get_response_data(response)
if isinstance(hosts, list):
self._API_BASE = random.choice(hosts)
return
raise ExtractorError('Unable to get available API hosts')
@staticmethod
def _prepare_url(url, title):
"""
Audius removes forward slashes from the uri, but leaves backslashes.
The problem is that the current version of Chrome replaces backslashes
in the address bar with a forward slashes, so if you copy the link from
there and paste it into youtube-dl, you won't be able to download
anything from this link, since the Audius API won't be able to resolve
this url
"""
url = urllib.parse.unquote(url)
title = urllib.parse.unquote(title)
if '/' in title or '%2F' in title:
fixed_title = title.replace('/', '%5C').replace('%2F', '%5C')
return url.replace(title, fixed_title)
return url
View on GitHub (pinned to 81ecd58b13)
Solutions
- Retry the command: discovery runs fresh each time and transient states pass
- Open https://api.audius.co/ in a browser; it should print {'data': [...]} with host URLs
- Update yt-dlp
- Check for interfering proxies if the payload looks like an error page
Defensive patterns
Strategy: retry
Validate before calling
import json, urllib.request
resp = json.load(urllib.request.urlopen('https://api.audius.co/'))
if not isinstance(resp.get('data'), list):
wait_and_retry() # discovery unusable; extractor would raise this error Try / catch
for attempt in range(3):
try:
info = ydl.extract_info(url, download=False)
break
except yt_dlp.utils.ExtractorError as e:
if 'Unable to get available API hosts' not in str(e) or attempt == 2:
raise
time.sleep(5) # discovery endpoint transient failure Prevention
- Pre-flight https://api.audius.co/ and confirm it returns a data list before batch jobs
- Retry discovery failures with short backoff before treating Audius as down
- Disable SSL-inspecting proxies for api.audius.co; they corrupt the discovery payload
When it happens
Trigger: The discovery endpoint responds 200 but its data is not a list - schema change on Audius' side, a message-only error dict (which first surfaces as 'API error'), or a mangled response from a proxy.
Common situations: Audius changing the discovery contract; transient gateway states; SSL-inspecting or captive-portal networks returning their own JSON.
Related errors
- API error: {}
- Unexpected API response
- An error occurred while receiving data. Try again
- Unable to get ID of the track
- Unable to get track ID from playlist
AI-assisted analysis of yt-dlp/yt-dlp@81ecd58b13 (2026-08-22).
Data as JSON: /api/errors/335c0a5ae3fce702.
Report an issue: GitHub.