{"record":{"id":"4cc5426a79ac4c9e","repo":"PrefectHQ/fastmcp","slug":"cimd-client-id-mismatch-document-says-doc-clien","errorCode":null,"errorMessage":"CIMD client_id mismatch: document says '{doc.client_id}' but was fetched from '{client_id_url}'","messagePattern":"CIMD client_id mismatch: document says '(.+?)' but was fetched from '(.+?)'","errorType":"validation","errorClass":"CIMDValidationError","httpStatus":null,"severity":"error","filePath":"fastmcp_slim/fastmcp/server/auth/cimd.py","lineNumber":418,"sourceCode":"            else:\n                self._remove_cache_entry(client_id_url)\n            return cached.doc\n\n        now = time.time()\n        policy = self._parse_cache_policy(response.headers, now)\n\n        try:\n            data = json.loads(response.content)\n        except json.JSONDecodeError as e:\n            raise CIMDValidationError(f\"CIMD document is not valid JSON: {e}\") from e\n\n        try:\n            doc = CIMDDocument.model_validate(data)\n        except Exception as e:\n            raise CIMDValidationError(f\"Invalid CIMD document: {e}\") from e\n\n        if str(doc.client_id).rstrip(\"/\") != client_id_url.rstrip(\"/\"):\n            raise CIMDValidationError(\n                f\"CIMD client_id mismatch: document says '{doc.client_id}' \"\n                f\"but was fetched from '{client_id_url}'\"\n            )\n\n        # Validate jwks_uri if present (SSRF check for JWKS endpoint)\n        if doc.jwks_uri:\n            jwks_uri_str = str(doc.jwks_uri)\n            try:\n                await validate_url(jwks_uri_str)\n            except SSRFError as e:\n                raise CIMDValidationError(\n                    f\"CIMD jwks_uri failed SSRF validation: {e}\"\n                ) from e\n\n        logger.info(\n            \"CIMD document fetched and validated: %s (client_name=%s)\",\n            client_id_url,\n            doc.client_name,","sourceCodeStart":400,"sourceCodeEnd":436,"githubUrl":"https://github.com/PrefectHQ/fastmcp/blob/1f021142978e0861cd910c8df4e8074bc7cf3978/fastmcp_slim/fastmcp/server/auth/cimd.py#L400-L436","documentation":"The CIMD spec requires that the client_id field inside the metadata document exactly match the URL the document was fetched from (modulo trailing slash). fetch() compares them after rstrip('/') and raises CIMDValidationError on mismatch, preventing clients from claiming someone else's identity.","triggerScenarios":"A CIMD document whose 'client_id' value differs from client_id_url — e.g. document hosted at https://a.example.com/client.json declaring client_id 'https://b.example.com/client.json', or http vs https mismatch, or trailing-path differences.","commonSituations":"Document copied from a staging environment to production without updating the embedded client_id; hosting moved to a new domain; trailing-slash or scheme (http/https) discrepancies; documents served from a redirect where fetch URL differs from canonical URL.","solutions":["Update the client_id field inside the hosted JSON document to exactly equal the URL where it is hosted","Check scheme, host, port, and path — all must match (only trailing '/' is ignored)","If the document was moved, update the embedded client_id and point clients at the new URL","Avoid serving the document from a URL that redirects; serve it directly at the canonical client_id URL"],"exampleFix":"// document hosted at https://app.example.com/client.json\n// before\n{\"client_id\": \"https://staging.example.com/client.json\", ...}\n// after\n{\"client_id\": \"https://app.example.com/client.json\", ...}","handlingStrategy":"validation","validationCode":"def client_id_matches(doc: dict, hosted_url: str) -> bool:\n    return str(doc.get(\"client_id\", \"\")).rstrip(\"/\") == hosted_url.rstrip(\"/\")","typeGuard":null,"tryCatchPattern":"try:\n    doc = await fetcher.get_client(client_id)\nexcept CIMDValidationError as e:\n    if \"client_id mismatch\" in str(e):\n        raise InvalidClientError(\"document client_id must equal hosting URL\") from e\n    raise","preventionTips":["Generate the client_id field programmatically from the hosting URL","Re-check the embedded client_id after any domain/hosting migration","Avoid redirects between the canonical client_id URL and the content"],"tags":["oauth","cimd","validation","client-id-mismatch"],"backgroundTag":"client-id-mismatch","analyzedSha":"1f021142978e0861cd910c8df4e8074bc7cf3978","analyzedAt":"2026-08-29T14:31:16.082Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}