RATE-002 recommended general

Graceful 429 handling

Rate-limited requests return proper 429 responses with helpful information

Question to ask

"What does your client actually do when it gets rate-limited?"

Verification guide

Severity: Recommended

When rate limits are hit, the response should be a proper 429 Too Many Requests with helpful information. The application shouldn't crash or return misleading errors.

Check automatically:

  1. Check for 429 status code handling:
# Explicit 429 responses in code
grep -rE "429|Too Many Requests|TooManyRequests" src/ lib/ app/ --include="*.ts" --include="*.js" --include="*.py" 2>/dev/null

# Rate limiter response configuration
grep -rE "statusCode.*429|status.*429|message.*rate|response.*limit" src/ lib/ app/ 2>/dev/null
  1. Check for Retry-After header (nice-to-have):
# Retry-After header configuration
grep -rE "Retry-After|retryAfter|retry-after" src/ lib/ app/ 2>/dev/null

# Rate limit headers
grep -rE "X-RateLimit|RateLimit-|rateLimit.*header" src/ lib/ app/ 2>/dev/null
  1. Check rate limiter error handling:
# Custom error handlers for rate limiting
grep -rE "onLimitReached|handler.*rate|limitHandler|exceeded" src/ lib/ app/ 2>/dev/null

# Error response format
grep -rE "res\.status\(429\)|response.*429|HttpStatus.*429" src/ lib/ app/ 2>/dev/null
  1. Actually test the rate limit (rigorous verification):
# If dev server is running, attempt to trigger rate limit
# This is a manual step - run in dev environment only

# Example: rapid requests to trigger limit
# for i in {1..100}; do curl -s -o /dev/null -w "%{http_code}\n" http://localhost:3000/api/endpoint; done | sort | uniq -c

# Check the response when limit is hit
# curl -v http://localhost:3000/api/endpoint (after triggering limit)

Ask user:

  • "What happens when a client hits the rate limit?"
  • "Have you tested hitting the rate limit in dev?"
  • "Does the response include retry information?"

Cross-reference with:

  • RATE-001 (rate limiting configured)
  • RATE-003 (documentation includes error responses)
  • MON-003 (HTTP logging - 429s should be logged)

Pass criteria:

  • Returns 429 Too Many Requests status code
  • Response body explains the limit was hit
  • Application doesn't crash or return 500
  • Retry-After header present (nice-to-have)

Fail criteria:

  • Returns 500 or generic error when limit hit
  • Application crashes under rate limiting
  • No indication client was rate limited
  • Response leaks internal implementation details

Evidence to capture:

  • Actual 429 response (test in dev)
  • Response body content
  • Headers included (Retry-After, X-RateLimit-*)
  • How rate limit errors are logged

Section

30. Rate Limiting

API & Security