OpenBB-finance/OpenBB · error · ValueError
Invalid username or password.
Error message
Invalid username or password.
What it means
Raised when the base64 token decodes cleanly but the username or password does not match the server_auth credentials, compared with secrets.compare_digest for timing safety. It surfaces as HTTP 401 with this detail. Credentials are wrong or stale — the request format was correct.
Source
Thrown at openbb_platform/extensions/mcp_server/openbb_mcp_server/app/auth.py:65
try:
scheme, token = auth_header.split()
if scheme.lower() != "bearer":
raise ValueError("Invalid authentication scheme.")
try:
decoded = base64.b64decode(token).decode("utf-8")
username, password = decoded.split(":", 1)
except (binascii.Error, ValueError) as e:
raise ValueError("Invalid base64-encoded token.") from e
expected_username, expected_password = self.server_auth
is_user_valid = secrets.compare_digest(username, expected_username)
is_pass_valid = secrets.compare_digest(password, expected_password)
if not (is_user_valid and is_pass_valid):
raise ValueError("Invalid username or password.")
request.state.user = {"username": username}
except (ValueError, HTTPException) as e:
detail = getattr(e, "detail", str(e))
raise HTTPException(
status_code=401,
detail=detail,
headers={"WWW-Authenticate": "Bearer"},
) from e
return True
async def verify_token(self, token: str) -> AccessToken | None:
"""Verify the token."""
if not self.server_auth:
return None
try:View on GitHub (pinned to 3e071fcc2c)
Solutions
- Verify the exact username/password pair configured as the server's server_auth.
- Regenerate the token after fixing credentials, trimming stray whitespace/newlines before encoding.
- Rotate/update the client's stored credentials if the server pair changed.
- Confirm you are pointing at the intended environment (dev vs prod server_auth).
Example fix
# before (password with trailing newline from file read)
pw = open("pw.txt").read() # "secret\n"
# after
pw = open("pw.txt").read().strip()
token = base64.b64encode(f"{user}:{pw}".encode()).decode() Defensive patterns
Strategy: retry
Validate before calling
def verify_credentials(candidate_user: str, candidate_pass: str, server_auth: tuple[str, str]) -> bool:
import secrets
u, p = server_auth
return secrets.compare_digest(candidate_user.strip(), u) and secrets.compare_digest(candidate_pass.strip(), p) Try / catch
for attempt, (user, pw) in enumerate(credential_sources):
try:
session.headers["Authorization"] = f"Bearer {make_bearer_token(user, pw)}"
await client.call_tool("list_categories", {})
break
except Exception as e:
if "Invalid username or password" not in str(getattr(e, "detail", e)) or attempt == len(credential_sources) - 1:
raise Prevention
- Strip whitespace/newlines from credentials before base64-encoding.
- Refresh stored credentials immediately after server-side rotation.
- Keep dev and prod credential sets clearly separated in the client config.
When it happens
Trigger: Typo in username or password; credentials rotated on the server but the client still caches the old pair; environment-specific credentials (dev vs prod) mixed up; whitespace accidentally included when building the token.
Common situations: Stale .env values after a password rotation; CI using expired test credentials; trailing newline in a password read from a file and included in the base64 payload.
Related errors
- Not authenticated
- Invalid authentication scheme.
- Invalid base64-encoded token.
- Unsupported file format. Please use .json or .env files.
- Provider fallback failed. [Providers] {msg}
AI-assisted analysis of OpenBB-finance/OpenBB@3e071fcc2c (2026-08-14).
Data as JSON: /api/errors/0e01e3a84dde6f99.
Report an issue: GitHub.