yt-dlp/yt-dlp · error · ExtractorError
Invalid password
Error message
Invalid password
What it means
PlaySuisseIE._perform_login (yt_dlp/extractor/playsuisse.py:207) performs the second auth step, POSTing the password to {LOGIN_BASE}/verification-srv/v2/authenticate/authenticate/password. Any ExtractorError from that call is re-labelled 'Invalid password' (expected=True); like the username step, the catch-all also hides network or schema errors behind this message.
Source
Thrown at yt_dlp/extractor/playsuisse.py:207
'request_id': request_id,
'medium_id': 'PASSWORD',
'type': 'password',
'identifier': username,
}).encode())['data']['exchange_id']['exchange_id']
except ExtractorError:
raise ExtractorError('Invalid username', expected=True)
try:
login_data = self._download_json(
f'{self._LOGIN_BASE}/verification-srv/v2/authenticate/authenticate/password', None,
'Submitting password', headers={'content-type': 'application/json'}, data=json.dumps({
'requestId': request_id,
'exchange_id': exchange_id,
'type': 'password',
'password': password,
}).encode())['data']
except ExtractorError:
raise ExtractorError('Invalid password', expected=True)
authorization_code = parse_qs(self._request_webpage(
f'{self._LOGIN_BASE}/login-srv/verification/login', None, 'Logging in',
data=urlencode_postdata({
'requestId': request_id,
'exchange_id': login_data['exchange_id']['exchange_id'],
'verificationType': 'password',
'sub': login_data['sub'],
'status_id': login_data['status_id'],
'rememberMe': True,
'lat': '',
'lon': '',
})).url)['code'][0]
self._ID_TOKEN = self._download_json(
f'{self._LOGIN_BASE}/proxy/token', None, 'Downloading token', data=b'', query={
'client_id': self._CLIENT_ID,
'redirect_uri': 'https://www.playsuisse.ch/auth',View on GitHub (pinned to 81ecd58b13)
Solutions
- Confirm the exact password in a browser login at playsuisse.ch.
- Quote the password properly on the CLI or store it in netrc to avoid shell mangling.
- Retry once to rule out the transient-failure case that shares this message.
- Update yt-dlp if both steps behave inconsistently, since JSON paths may have moved.
Defensive patterns
Strategy: try-catch
Type guard
from yt_dlp.utils import ExtractorError
def is_playsuisse_invalid_password(e: BaseException) -> bool:
"""True for the 'Invalid password' wrap from the authenticate/password step."""
return isinstance(e, ExtractorError) and e.expected and str(e) == 'Invalid password' Try / catch
from yt_dlp.utils import ExtractorError
try:
ydl.download([url])
except ExtractorError as e:
if e.expected and str(e) == 'Invalid password':
raise CredentialsError('playsuisse rejected the password') from e
raise Prevention
- Reach this stage only with a username that already passed the initiate step — debug the password, not the identifier.
- Quote passwords safely on the CLI or use netrc to avoid shell mangling.
- Retry once: the same message can wrap a transient failure of the authenticate call.
When it happens
Trigger: The username step succeeded (a valid exchange_id was obtained) but the password submission failed: wrong password for a known account, or a transient/structural failure in the authenticate/password request.
Common situations: Stale password in netrc after a reset; password containing characters mangled by shell quoting on the command line; occasional network hiccup reported misleadingly as 'Invalid password'.
Related errors
- Invalid username
- Unable to login: {error}
- Unable to login: {error}
- Unable to login: {error}
- No video formats found!
AI-assisted analysis of yt-dlp/yt-dlp@81ecd58b13 (2026-08-22).
Data as JSON: /api/errors/837c4723390e0489.
Report an issue: GitHub.