{"record":{"id":"346f92f058185994","repo":"PrefectHQ/fastmcp","slug":"oauth-server-rejected-the-static-client-credential","errorCode":null,"errorMessage":"OAuth server rejected the static client credentials. Verify that the client_id (and client_secret, if provided) are correct and that the client is registered with the server.","messagePattern":"OAuth server rejected the static client credentials\\. Verify that the client_id \\(and client_secret, if provided\\) are correct and that the client is registered with the server\\.","errorType":"exception","errorClass":"ClientNotFoundError","httpStatus":null,"severity":"error","filePath":"fastmcp_slim/fastmcp/client/auth/oauth.py","lineNumber":475,"sourceCode":"                \"or use it with Client(auth=...) which provides the URL automatically.\"\n            )\n        try:\n            # First attempt with potentially cached credentials\n            async with aclosing(super().async_auth_flow(request)) as gen:\n                response = None\n                while True:\n                    try:\n                        # First iteration sends None, subsequent iterations send response\n                        yielded_request = await gen.asend(response)  # ty: ignore[invalid-argument-type]\n                        response = yield yielded_request\n                    except StopAsyncIteration:\n                        break\n\n        except (ClientNotFoundError, ExpiredClientRegistrationError) as exc:\n            # Static credentials are fixed — retrying won't help. Surface the\n            # error so the user can correct their client_id / client_secret.\n            if self._static_client_info is not None:\n                raise ClientNotFoundError(\n                    \"OAuth server rejected the static client credentials. \"\n                    \"Verify that the client_id (and client_secret, if provided) \"\n                    \"are correct and that the client is registered with the server.\"\n                ) from exc\n\n            logger.debug(\n                \"OAuth client registration is invalid, clearing cache and retrying...\"\n            )\n            # Clear cached state and retry once\n            self._initialized = False\n            await self.token_storage_adapter.clear()\n\n            # Retry with fresh registration\n            async with aclosing(super().async_auth_flow(request)) as gen:\n                response = None\n                while True:\n                    try:\n                        yielded_request = await gen.asend(response)  # ty: ignore[invalid-argument-type]","sourceCodeStart":457,"sourceCodeEnd":493,"githubUrl":"https://github.com/PrefectHQ/fastmcp/blob/1f021142978e0861cd910c8df4e8074bc7cf3978/fastmcp_slim/fastmcp/client/auth/oauth.py#L457-L493","documentation":"When the OAuth flow fails with ClientNotFoundError or ExpiredClientRegistrationError and the provider was configured with static client credentials (static_client_info), retrying cannot help — the credentials are fixed. FastMCP re-raises as ClientNotFoundError telling you to verify the client_id/client_secret and that the client is registered with the server.","triggerScenarios":"Using OAuth(..., static_client_id=... / client_metadata with fixed credentials) against a server that does not have that client registered, or whose registration was deleted/expired; the inner flow raised ClientNotFoundError or ExpiredClientRegistrationError, and the static-credentials branch in async_auth_flow converts it into this error.","commonSituations":"Typos in the configured client_id/secret; credentials copied from another environment; server database wiped so the statically referenced client no longer exists; client secret expired on the provider side.","solutions":["Verify the client_id (and client_secret) values are correct for that exact server and correct any typos.","Register the client with the OAuth server (or create it in the provider's admin console) if it does not exist.","If the secret expired, rotate it and update the configuration.","Alternatively drop the static credentials and let FastMCP perform dynamic client registration."],"exampleFix":"// before: stale static credentials\nauth = OAuth(mcp_url=URL, static_client_id='old-client-id', static_client_secret='old-secret')\n// after: correct, currently registered credentials\nauth = OAuth(mcp_url=URL, static_client_id='current-client-id', static_client_secret='current-secret')","handlingStrategy":"validation","validationCode":"# Confirm the static client exists before running the flow\ntoken_resp = httpx.post(f'{issuer}/oauth/token', data={'client_id': CLIENT_ID, 'client_secret': CLIENT_SECRET, 'grant_type': 'client_credentials'})\nif token_resp.status_code in (400, 401):\n    raise ValueError('Static OAuth client credentials are not registered/valid at this server')","typeGuard":null,"tryCatchPattern":"from fastmcp.client.auth import ClientNotFoundError\ntry:\n    async with client:\n        await client.list_tools()\nexcept ClientNotFoundError as e:\n    if 'static client credentials' in str(e):\n        fix_or_register_static_client()  # cannot self-heal: credentials are fixed\n    raise","preventionTips":["Keep static client_id/secret in per-environment config and verify them against the right server.","Prefer dynamic client registration unless the provider forbids it, so credentials can self-heal.","Track client secret expiry and rotate before it lapses.","After a server wipe/redeploy, re-register static clients or switch to dynamic registration."],"tags":["oauth","credentials","auth","configuration"],"backgroundTag":"invalid-oauth-client-credentials","analyzedSha":"1f021142978e0861cd910c8df4e8074bc7cf3978","analyzedAt":"2026-08-29T14:31:16.082Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}