Identity probes for direct API tokens are rate-limited at scale (~24k/h) and amplify themselves by retrying 429s
Maintainers usually reply within 1 day
Nobody has claimed this yet.
- #230 by @mattzcarey — closed without merging
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 55/100
- Issue type
- Bug
- Clarity
- Mostly clear
- Activity status
- Active
- Tech stack
- typescript
- Domain
- api, backend, performance
Research direction
Start by tracing the identity probe paths and their use of fetchWithRetry, including the account and user/legacy endpoint probes. Verify how successful identities are cached and where concurrent misses are handled. Done means 429s are surfaced without probe retries, the Retry-After window is briefly cached for that token, and successful identity caching remains 30 days.
Written by the indexing model from the issue text.
Description
Rewritten after looking at production (the original plan here, shortening the 30-day identity cache, would make this worse).
What production shows (cloudflare-api-mcp, last hour, Workers Observability)
| per hour | |
|---|---|
POST /mcp requests |
~1.24M |
api_token_identity_probe log lines |
~23.6k (0 from the OAuth callback probe) |
…of which 429 retries (fetchWithRetry: 429) |
~18.5k |
| probes that failed after all retries | ~5.3k |
MCP requests answered 429 temporarily_unavailable |
~4.1k |
All-time on the Issues tab: 4.79M fetchWithRetry failed … /accounts … 429 and 1.59M … /user … 429. Both the account-token path (per_page=5, ~6.4k/h) and the user/legacy path (/user + per_page=31, ~8.9k/h each) are being rate-limited.
Why it amplifies itself
- Retrying 429s. Every identity probe goes through
fetchWithRetry(up to 4 attempts with about 1 s backoff), and user tokens probe two endpoints in parallel. One rate-limited request becomes up to 8 more requests against the same quota, spending the user's own Cloudflare API budget, which their real tool calls then also run out of. - Failures aren't cached. Only successful identities are cached (30 days), so every request from a rate-limited token probes again.
- Concurrent misses aren't coalesced. A new token's first burst of requests all miss the cache together.
Fix
- Don't retry 429s in identity probes. Surface
temporarily_unavailablewith Cloudflare'sRetry-Afterstraight away. - Cache a 429 briefly (for the
Retry-Afterwindow) so repeat requests from that token back off instead of re-probing. - Keep the 30-day success cache. Revoked-token staleness is a real trade-off, but reducing it by probing more often is the wrong lever while probes are the top error. Revisit once probe volume is under control.
Related: about 24k/h of the probes are for tokens in workers-oauth-provider's own format (expired MCP access tokens), which the library hands to resolveExternalToken. That's being fixed in the library (cloudflare/workers-oauth-provider, linked from here).
- Dominant language
- TypeScript
- Stars
- 1k
- Forks
- 151
- Avg merge
- 2d 3h
- Merged PRs (30d)
- 68
Getting set up
- No Dockerfile or Docker Compose file
- No pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from cloudflare/mcp
-
[Connection guide] Claude CodePossibly taken @umeraamir69 claimed this 12 days ago. Openenhancement good first issue
Difficulty 1/5 Under an hour Newbie friendliness 72/100
cloudflare/mcp#39 · 6 comments · 1 reaction ·
Maintainers usually reply within 1 day
-
enhancement
Difficulty 5/5 Over a week Newbie friendliness 35/100
cloudflare/mcp#368 ·
Maintainers usually reply within 1 day
-
bug
Difficulty 4/5 3-5 days Newbie friendliness 42/100
cloudflare/mcp#363 · 1 reaction ·
Maintainers usually reply within 1 day
-
Worker bundle is 2 MB unminified with 106 ms startupPossibly taken @mattzcarey claimed this 5 days ago. Openenhancement
cloudflare/mcp#348 · 1 assignee ·
Maintainers usually reply within 1 day
-
GlobalOutbound uses 3.5 ms of CPU per proxied execute requestPossibly taken @mattzcarey claimed this 5 days ago. Openenhancement
cloudflare/mcp#347 · 1 assignee ·
Maintainers usually reply within 1 day
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
kunchenguid/gh-axi#247 ·
Maintainers usually reply within 1 day
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
lidge-jun/opencodex#8101 · 2 comments ·
Maintainers usually reply within 1 day
-
effort:S P3 refactor
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
nightscout/nocturne#3243 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
JuliusBrussee/caveman#1449 ·
Maintainers usually reply within 1 day