MCP Gateway authenticates in two places: your client → Portkey (using your API key or OAuth), and Portkey → the MCP server (using OAuth, client credentials, or headers). Most “authorization failed” messages come from the second step, even when your client only shows a generic error.
Find your issue
Can't connect / access denied
401 / 403 / 404, “Unable to verify user access”
OAuth won't complete
DCR errors, wrong scope, redirect issues
Changes not taking effect
Updated config still shows old behavior
Self-hosted setup
Gateway URL, redirect URI, base URL
Quick triage by status code
| Status | What it means | First thing to check |
|---|---|---|
401 | Missing/expired token, or the MCP server needs you to sign in | Re-authenticate; if prompted, complete the server’s sign-in |
403 | You’re authenticated but not allowed | Wrong workspace/server in the URL, or you don’t have access to that server |
404 | Server not found | The slug in your URL is wrong, or the server isn’t registered in this workspace |
500 “Unable to verify user access” | The gateway couldn’t confirm your access | See API key type below |
Can’t connect or access denied
Check your API key type and permissions
Your Portkey API key must have themcp.invoke permission. Create or edit it under Settings → API Keys.
There are two key types, and they behave differently with MCP servers:
| MCP server auth type | Works with Service key | Works with User key |
|---|---|---|
| None / Custom Headers / Client Credentials | Yes | Yes |
| OAuth 2.1 (per-user) | Not for per-user sign-in | Yes |
Per-user OAuth needs a user identity. Servers configured with OAuth 2.1 give each user their own connection to the upstream service (your GitHub vs. a teammate’s GitHub). Connect with a credential that identifies a user (a User API key or an OAuth/IdP login). A shared service key can be used for servers that use None, Custom Headers, or Client Credentials, where everyone shares the same upstream access.
Check the gateway URL
The URL pattern ishttps://mcp.portkey.ai/{slug}/mcp, where {slug} is the slug from the MCP Registry—not a UUID. You can copy the exact URL from the server’s page in the Registry.
A 403/404 usually means the slug is wrong, the server isn’t provisioned to your workspace, or your key belongs to a different workspace.
OAuth with the MCP server fails
”Incompatible auth server: does not support dynamic client registration”
Some services (for example Snowflake, or servers fronted by an enterprise identity provider like Okta or Entra) don’t support automatic OAuth client registration. Portkey’s default flow tries to register itself and the service rejects it. Fix: create an OAuth client (client ID + secret) with the service or its identity provider, then add it in the integration’s Advanced Configuration so Portkey uses your pre-registered client:”invalid_scope” or the wrong scope appears during sign-in
You set a scope inoauth_metadata.scope, but sign-in fails with invalid_scope (or the identity provider shows a different scope than you expected).
Fix:
- Make sure the scope you need is set in
oauth_metadata.scope. - Confirm that exact scope exists at your identity provider and is allowed for your OAuth app / policy. If it isn’t defined or allowed, the provider drops or rejects it.
- Verify by watching the browser during sign-in—the authorization URL’s
scope=value should match what you configured.
The redirect/callback doesn’t work
The OAuth callback URL is fixed and must match in your OAuth app exactly:mcp.portkey.ai (see Self-hosted and hybrid gateways).
”Protected resource … does not match expected …”
The server URL you registered doesn’t match the address the server advertises—usually because the path is missing. Fix: register the URL including the path the server expects, which is almost always…/mcp. You can confirm the expected value:
resource value it returns.
”Select the correct organisation” (or similar)
Some services (for example Notion) ask you to choose a workspace or organization during sign-in. Picking the wrong one—or none—leads to a confusing error. Fix: complete the sign-in and select the correct organization. If you already authorized the wrong one, disconnect/clear the connection for that server and sign in again.Configuration changes aren’t taking effect
You updated an MCP server’s configuration (URL, auth, scopes), but the gateway still behaves as if nothing changed—or a server that failed once keeps failing even after you fixed it. Why: server configuration and connections are cached for a short time, and an existing (stale) connection can linger. Fix:- Wait a short while for the change to propagate, then retry.
- Disconnect and reconnect the server from your client, and re-run the sign-in so a fresh connection is created.
- If it still uses the old behavior, confirm you edited the integration in the same workspace/organization your client is connecting through.
Frequent reconnects / “tokens expire too quickly”
Users have to re-authorize a connected server far more often than expected. What to know: access tokens are short-lived (about 1 hour) and refresh tokens are long-lived (about 30 days); the gateway refreshes them automatically, so you shouldn’t need to reconnect often. Fix:- Make sure you’re on the latest gateway version (especially for self-hosted deployments).
- If reconnects continue, contact support with the server slug and timestamps so the team can review the token refresh logs.
OAuth discovery returns a 404
Your client can’t start sign-in because OAuth discovery points it at an unreachable address. Fix: confirm discovery is reachable:Self-hosted and hybrid gateways
If you run the gateway yourself (instead ofmcp.portkey.ai):
- Use your own gateway host in the client URL:
https://<your-gateway-host>/{slug}/mcp. - Set the OAuth callback in any upstream OAuth app to
https://<your-gateway-host>/oauth/upstream-callback. - Set
MCP_GATEWAY_BASE_URLto your public gateway URL (for examplehttps://<your-gateway-host>). The gateway uses this to construct callback and discovery URLs—if it’s wrong, OAuth and discovery fail. - Make sure your ingress forwards the
Hostheader so the server advertises its public URL (not an internal address).
Enterprise: external_auth_config returns 403
external_auth_config (where the gateway brokers your own identity provider directly) is available on self-hosted/enterprise deployments only and is blocked on managed SaaS.
Fix: on SaaS, use oauth_metadata with a pre-registered OAuth client instead. See External OAuth.
Still stuck?
Contact support@portkey.ai with:- Your workspace ID
- The MCP server slug
- The full error message (and
request_idif shown) - The MCP client you’re using (Claude Desktop, Cursor, etc.)
Related
Authentication
How the two authentication layers work.
OAuth Client Metadata
All
oauth_metadata fields and pre-registered clients.MCP server guides
Per-service setup guides (Snowflake, GitHub, Slack, and more).
Observability
Inspect tool calls, auth, and errors per request.

