Rate limit errors (HTTP 429) handled gracefully
Why it matters
HTTP 429 (Too Many Requests) responses from third-party APIs — OpenAI, Stripe, SendGrid, Twilio — are not errors; they are instructions. An application that treats them as generic failures and retries immediately makes the rate-limit situation worse and may get its API key suspended. CWE-703 (improper check for exceptional conditions) applies. Users who trigger rate-limited operations see cryptic failures when they should see a clear message like 'You've sent too many requests. Please wait 60 seconds.' The Retry-After header provides the exact wait time — ignoring it is wasteful and user-hostile.
Severity rationale
Low severity for individual users, but repeated unhandled 429s can trigger API key suspension, causing a service-wide outage for all users simultaneously.
Remediation
Detect 429 responses explicitly, extract the Retry-After header, and surface a user-readable wait message. Do not auto-retry 429s without respecting the header delay.
// lib/api-client.ts
export async function apiFetch(url: string, options?: RequestInit) {
const res = await fetch(url, options)
if (res.status === 429) {
const retryAfter = parseInt(res.headers.get('Retry-After') ?? '60', 10)
throw new RateLimitError(
`Too many requests. Please wait ${retryAfter} seconds before trying again.`,
retryAfter
)
}
return res
}
In the UI, catch RateLimitError and show a countdown or disabled button with the remaining wait time rather than a generic error toast.
DetectionPro
The detection method for this pattern is part of AuditBuffet Pro.
The full method (what to look for, pass and fail conditions, and how results get reported) ships inside the Error Resilience Audit. The pattern definition, severity rationale, and remediation remain openly licensed under CC-BY-4.0.
External references
- cwe · CWE-703 — Improper Check or Handling of Exceptional Conditions
- iso-25010:2011 · reliability.fault-tolerance
Taxons
History
- 2026-04-18·v1.0.0·Initial import from error-resilience·automated