{"record":{"id":"872f89d3b95437e4","repo":"PrefectHQ/fastmcp","slug":"server-overloaded-please-retry","errorCode":null,"errorMessage":"Server overloaded, please retry","messagePattern":"Server overloaded, please retry","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"fastmcp_slim/fastmcp/server/auth/cimd.py","lineNumber":642,"sourceCode":"\n        # Check if JTI was already used (and hasn't expired from cache)\n        if jti in self._jti_cache:\n            cached_exp = self._jti_cache[jti]\n            if cached_exp > now:  # Still valid in cache\n                raise ValueError(f\"Assertion replay detected: jti {jti} already used\")\n            # Expired in cache, can be reused (clean it up)\n            del self._jti_cache[jti]\n\n        # Emergency size limit (shouldn't hit with proper TTL cleanup)\n        if len(self._jti_cache) >= self._jti_cache_max_size:\n            self._cleanup_expired_jtis()\n            # If still over limit after cleanup, reject to prevent DoS\n            if len(self._jti_cache) >= self._jti_cache_max_size:\n                self.logger.warning(\n                    \"JTI cache at max capacity (%d), possible attack\",\n                    self._jti_cache_max_size,\n                )\n                raise ValueError(\"Server overloaded, please retry\")\n\n        # Add to cache with expiration time\n        # Use the assertion's exp claim so it stays cached until it would expire anyway\n        self._jti_cache[jti] = exp\n\n        self.logger.debug(\n            \"JWT assertion validated successfully for client %s\", client_id\n        )\n        return True\n\n    def _extract_public_key_from_jwks(self, token: str, jwks: dict) -> str:\n        \"\"\"Extract public key from inline JWKS.\n\n        Args:\n            token: JWT token to extract kid from\n            jwks: JWKS document containing keys\n\n        Returns:","sourceCodeStart":624,"sourceCodeEnd":660,"githubUrl":"https://github.com/PrefectHQ/fastmcp/blob/1f021142978e0861cd910c8df4e8074bc7cf3978/fastmcp_slim/fastmcp/server/auth/cimd.py#L624-L660","documentation":"Raised by validate_assertion when the server's JTI replay cache has reached _jti_cache_max_size and purging expired entries did not free space. The server deliberately refuses new assertions to prevent a DoS via cache flooding — the message tells the caller to try again later.","triggerScenarios":"A flood of unique-jti assertions (legit high traffic or an attack) filling the cache with entries whose exp values are far in the future; a configuration with a very small _jti_cache_max_size; an attacker spamming assertions to exhaust replay-tracking capacity.","commonSituations":"High-throughput client fleets sharing one validator instance; mis-tuned cache sizing after deployment; an actual DoS attempt against the token endpoint.","solutions":["Retry the request after a short backoff — legitimate transient overload usually clears as cached jtis expire","Increase _jti_cache_max_size if traffic legitimately generates many concurrent assertions","Investigate logs ('JTI cache at max capacity') for abusive clients and rate-limit them"],"exampleFix":"// before\nvalidator = CIMDValidator(..., _jti_cache_max_size=1000)  # too small for fleet\n// after\nvalidator = CIMDValidator(..., _jti_cache_max_size=100000)","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"import time\nfor attempt in range(3):\n    try:\n        validator.validate_assertion(mint_assertion(client_id), client_id, jwks)\n        break\n    except ValueError as e:\n        if \"Server overloaded\" in str(e):\n            time.sleep(2 ** attempt)\n            continue\n        raise","preventionTips":["Apply exponential backoff when the server signals overload","Size _jti_cache_max_size for peak concurrent assertion volume","Monitor 'JTI cache at max capacity' warnings and rate-limit abusive clients"],"tags":["oauth","security","dos-protection","rate-limiting"],"backgroundTag":"server-overloaded","analyzedSha":"1f021142978e0861cd910c8df4e8074bc7cf3978","analyzedAt":"2026-08-29T14:31:16.082Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}