microsoft/semantic-kernel · error · HTTPException
Invalid credentials
Error message
Invalid credentials
What it means
Thrown by the MCP OAuth sample after the state is validated but the submitted username/password do not equal the configured demo credentials (self.settings.demo_username / demo_password). It is a plain HTTP 401 rejecting the login form submission. The sample uses fixed demo credentials, not a real user store.
Source
Thrown at python/samples/demos/mcp_with_oauth/server/mcp_simple_auth/simple_auth_provider.py:175
"""Handle simple authentication callback and return redirect URI."""
state_data = self.state_mapping.get(state)
if not state_data:
raise HTTPException(400, "Invalid state parameter")
redirect_uri = state_data["redirect_uri"]
code_challenge = state_data["code_challenge"]
redirect_uri_provided_explicitly = state_data["redirect_uri_provided_explicitly"] == "True"
client_id = state_data["client_id"]
resource = state_data.get("resource") # RFC 8707
# These are required values from our own state mapping
assert redirect_uri is not None
assert code_challenge is not None
assert client_id is not None
# Validate demo credentials
if username != self.settings.demo_username or password != self.settings.demo_password:
raise HTTPException(401, "Invalid credentials")
# Create MCP authorization code
new_code = f"mcp_{secrets.token_hex(16)}"
auth_code = AuthorizationCode(
code=new_code,
client_id=client_id,
redirect_uri=AnyHttpUrl(redirect_uri),
redirect_uri_provided_explicitly=redirect_uri_provided_explicitly,
expires_at=time.time() + 300,
scopes=[self.settings.mcp_scope],
code_challenge=code_challenge,
resource=resource, # RFC 8707
)
self.auth_codes[new_code] = auth_code
# Store user data
self.user_data[username] = {
"username": username,View on GitHub (pinned to c028a0c7dc)
Solutions
- Use the exact demo credentials the server is configured with — check DEMO_USERNAME and DEMO_PASSWORD in the server's env/.env and match them exactly.
- Use the pre-filled defaults in the rendered login form (demo_user / demo_password) if you have not customized the env.
- Trim leading/trailing whitespace from submitted values and confirm no caps-lock/autocorrect altered the password.
- Restart the server after editing .env so the new settings are loaded.
Example fix
# .env for the sample server DEMO_USERNAME=demo_user DEMO_PASSWORD=demo_password # Submit exactly these in the login form.
Defensive patterns
Strategy: validation
Validate before calling
import os
assert os.getenv('DEMO_USERNAME'), 'DEMO_USERNAME not set'
assert os.getenv('DEMO_PASSWORD'), 'DEMO_PASSWORD not set
# Submit exactly these values in the login form. Try / catch
try:
redirect = await provider.handle_simple_callback(username, password, state)
except HTTPException as e:
if e.status_code == 401:
# surface 'check DEMO_USERNAME/DEMO_PASSWORD' to the user
...
raise Prevention
- Echo the configured demo credentials into the login form so testers copy them exactly.
- Restart the server after editing .env so new demo credentials load.
- Trim whitespace from env values.
- Keep a note of the current demo credentials next to the sample.
When it happens
Trigger: Submitting the /login/callback form with credentials that differ from settings.demo_username/demo_password; leaving the .env values at defaults while typing other values; misconfigured DEMO_USERNAME/DEMO_PASSWORD env vars.
Common situations: Developer changed the demo credential env vars on the server but submitted the old defaults shown in the form HTML; form pre-fills 'demo_user'/'demo_password' but env was overridden to something else; copy-paste whitespace differences.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Invalid state parameter
- Invalid authorization code
- Refresh tokens not supported
- OAuth error: {self.callback_data['error']}
- Timeout waiting for OAuth callback
AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13).
Data as JSON: /api/errors/94496cf6158d98b4.
Report an issue: GitHub.