Your authorization server supports PKCE. You tested it. A client still refuses to start the login against your MCP server and reports that the server does not support PKCE.
The usual cause is not the PKCE implementation. It is one field missing from the metadata document that clients read before they do anything else.
Why a missing field stops the login
PKCE protects the authorization code. The client creates a secret, sends a hash of it with the authorization request and proves it knows the secret when it exchanges the code for a token. A stolen code is useless without that secret.
OAuth has no way for a client to ask whether a server supports PKCE. The only signal is the authorization server metadata. The MCP authorization spec is strict about what follows from that. Clients must verify PKCE support before they proceed. If code_challenge_methods_supported is absent from the metadata, the spec says the authorization server does not support PKCE and the client must refuse to proceed.
So a server that enforces PKCE perfectly but does not say so looks the same to a compliant client as a server without PKCE. The client stops before the browser opens.
What the metadata has to say
GET /.well-known/oauth-authorization-server
{
"issuer": "https://auth.example.com",
"authorization_endpoint": "https://auth.example.com/authorize",
"token_endpoint": "https://auth.example.com/token",
"code_challenge_methods_supported": ["S256"]
}The value matters too. MCP clients must use the S256 method. A server that only lists plain gives them nothing they are allowed to use. The same rule applies if your server publishes OpenID Connect discovery instead: the field has to be in that document.
How common it is
In a sweep of 277 public MCP server URLs on 2026-11-06, 264 were reachable and 3 of them served OAuth metadata without S256 in code_challenge_methods_supported. That only counts servers whose metadata could be read without credentials.
Check your server
npx -y @patchbay-nebius/agent audit https://mcp.example.com/mcpIf the metadata does not list S256 you get finding AUTH-003 at high severity. No flags are needed and the browser scanner runs the same check. The check reads the metadata. It does not run a login, so it cannot tell you whether the server enforces PKCE at runtime.
The fix
- Add
"code_challenge_methods_supported": ["S256"]to the authorization server metadata. - Reject authorization requests that come without a
code_challenge. Advertising PKCE while still accepting requests without it protects nobody. - Do not accept
plain. MCP clients are required to useS256.
With a hosted identity provider this is usually a per application setting called something like "require PKCE". Check the metadata document again after you change it.
PKCE is one of several things a client reads from the same document. If you are fixing the metadata anyway, look at client registration in the same pass.