RL
GitHub
Documentation

FAQ and Troubleshooting

Common errors, missing headers, and Redis outages.

FAQ and Troubleshooting

This page collects common issues and the fastest fixes for each one.

I am missing X-RateLimit-* headers

This usually means the request never reached the rate limiter filter or the endpoint is excluded from rate limiting.

Check these first:

  • The endpoint is not in the exclusion list (/actuator/*, /swagger-ui/*, /v3/api-docs/*, /api/config/v2).
  • A gateway or cache is not stripping response headers.
  • The service you are hitting is the rate limiter service, not an upstream proxy.

If headers are still missing, confirm that the filter is registered and that your endpoint path matches the configured rate-limit.endpoints patterns.

I get 429 Too Many Requests immediately

This usually means the limit is too low or the keying dimension is too broad. If all traffic appears to come from a single IP (for example, a gateway IP), you will hit limits immediately.

Fixes:

  • Configure trusted proxies so client IPs are extracted correctly.
  • Increase capacity or maxRequests temporarily to validate configuration.
  • Confirm that user tier is resolved correctly so you are not falling into the lowest tier.

The limit resets earlier or later than expected

Check which algorithm you configured:

  • Fixed Counter resets on the TTL boundary, not on a rolling window.
  • Sliding Window Log resets when the last request falls out of the window.
  • Token Bucket refills continuously based on elapsed time.

If your X-RateLimit-ResetOn feels inconsistent, confirm that system clocks are synced and that you are not relying on local server time instead of Redis time.

MongoDB overrides do not apply

Overrides require a match on IP, endpoint, user tier, and optionally method. If any part does not match at runtime, the override is skipped.

Checklist:

  • The override document exists in rate_limit_config.
  • The runtime user tier matches the stored userTier.
  • The endpoint path matches exactly.
  • The HTTP method matches when specified.

If MongoDB is down, the service returns 503 and overrides cannot be read or written.

Redis outages return 503

The rate limiter depends on Redis for every decision. If Redis is unavailable, requests fail with 503 Service Unavailable.

Mitigations:

  • Run Redis with replication or Sentinel for failover.
  • Monitor redis_up and alert before complete failure.
  • Consider a fail-open or local fallback strategy if your risk model allows it.

I see uneven behavior across instances

This can happen because in-memory configuration cache is not shared across instances. The first request for a new IP may hit MongoDB on one instance but not on another.

If this matters, use a shared cache or tolerate a small latency difference for first requests.

Prometheus memory is growing fast

High cardinality metrics are the common cause. If you label metrics with raw uri values, time series can explode.

Fixes:

  • Aggregate URIs by path prefix in your scrape config.
  • Limit the number of labeled endpoints you expose.
  • Monitor Prometheus heap and reduce retention if needed.

I changed limits but behavior did not change

Make sure you updated the correct configuration source. MongoDB overrides have higher priority than YAML, so YAML changes will not apply if a matching MongoDB document exists.

Delete or update the override document, then re-test.