Summary
Finding
Ran pitstop-check against the MCP transport layer:
src/transports/streamable-http-transport.ts:153 — 429 handled without Retry-After
Why it matters
In MCP transport, a 429 can mean different things:
- Transient pressure → wait and retry
- Quota exhaustion → do not retry
When Retry-After is ignored, the transport retries quota exhaustion cases that can't recover until the window resets.
Example
curl -s -X POST https://web-production-273d3.up.railway.app/classify \
-H "Content-Type: application/json" \
-d '{"status":429,"headers":{"retry-after":"600"}}'
Returns STOP — do not retry.
Static check: github.com/SirBrenton/pitstop-check
Reproduction steps
- Clone the repo and run
pitstop-check against the transport layer:
npx pitstop-check src/transports/streamable-http-transport.ts
- Observe warning at line 153:
429 handled without Retry-After — likely incorrect retry behavior
Expected behavior:
429 responses with a Retry-After header should use that value to determine wait time before retry. Quota exhaustion cases (long Retry-After) should not retry at all.
Actual behavior:
All 429s handled uniformly without inspecting Retry-After.
No distinction between transient pressure and quota exhaustion.
Environment
Static analysis only — no runtime reproduction required.
- OS: macOS
- Node: current LTS
- Transport: streamable-http-transport.ts
- Finding confirmed in current main branch (cloned 2026-04-02)
- Client: n/a (static code analysis)
Summary
Finding
Ran
pitstop-checkagainst the MCP transport layer:src/transports/streamable-http-transport.ts:153— 429 handled without Retry-AfterWhy it matters
In MCP transport, a 429 can mean different things:
When Retry-After is ignored, the transport retries quota exhaustion cases that can't recover until the window resets.
Example
Returns
STOP— do not retry.Static check:
github.com/SirBrenton/pitstop-checkReproduction steps
pitstop-checkagainst the transport layer:429 handled without Retry-After — likely incorrect retry behaviorExpected behavior:
429 responses with a
Retry-Afterheader should use that value to determine wait time before retry. Quota exhaustion cases (long Retry-After) should not retry at all.Actual behavior:
All 429s handled uniformly without inspecting
Retry-After.No distinction between transient pressure and quota exhaustion.
Environment
Static analysis only — no runtime reproduction required.