# 429 Too Many Requests: Retry-After header value is malformed or missing

- **ID:** `api/rate-limit-exceeded-retry-after-malformed`
- **Domain:** api
- **Category:** resource_error
- **Verification:** ai_generated
- **Fix Rate:** 70%

## Root Cause

Server returns 429 with a Retry-After header that has an invalid format (e.g., non-numeric, negative, or missing entirely), causing clients to fail to implement proper backoff.

## Version Compatibility

| Version | Status | Introduced | Deprecated |
|---------|--------|------------|------------|
| Nginx 1.24.0 | active | — | — |
| Cloudflare 2024 | active | — | — |
| AWS API Gateway 2024 | active | — | — |
| Kong 3.5.0 | active | — | — |

## Workarounds

1. **Implement robust Retry-After parsing that handles both seconds and HTTP-date formats: `const retryAfter = response.headers.get('Retry-After'); let delay; if (retryAfter && /^\d+$/.test(retryAfter)) { delay = parseInt(retryAfter) * 1000; } else if (retryAfter) { delay = new Date(retryAfter).getTime() - Date.now(); } else { delay = 5000; }`** (85% success)
   ```
   Implement robust Retry-After parsing that handles both seconds and HTTP-date formats: `const retryAfter = response.headers.get('Retry-After'); let delay; if (retryAfter && /^\d+$/.test(retryAfter)) { delay = parseInt(retryAfter) * 1000; } else if (retryAfter) { delay = new Date(retryAfter).getTime() - Date.now(); } else { delay = 5000; }`
   ```
2. **Use exponential backoff with jitter as fallback when Retry-After is missing: `delay = Math.min(60000, Math.pow(2, attempt) * 1000 + Math.random() * 1000)`** (80% success)
   ```
   Use exponential backoff with jitter as fallback when Retry-After is missing: `delay = Math.min(60000, Math.pow(2, attempt) * 1000 + Math.random() * 1000)`
   ```
3. **Contact API provider to fix Retry-After header format, and in the meantime, parse it leniently (e.g., extract first numeric value)** (70% success)
   ```
   Contact API provider to fix Retry-After header format, and in the meantime, parse it leniently (e.g., extract first numeric value)
   ```

## Dead Ends

- **** — Hardcoding a fixed retry delay (e.g., 5 seconds) instead of parsing Retry-After (80% fail)
- **** — Ignoring Retry-After and retrying immediately, causing repeated 429 responses (90% fail)
- **** — Assuming Retry-After is always in seconds (when it could be an HTTP-date) (65% fail)
