Common issues
Rate limits not being enforced
Rate limits not being enforced
Symptoms:
- Requests exceed configured limits without returning HTTP 429
- No rate limiting appears to be active
-
Rate limiter is disabled in configuration
-
Annotation has
enabled=false -
Method is not proxied by Spring AOP
- Ensure the annotated method is
public - Call the method from outside the class (not
this.method()) - The class must be a Spring bean (
@Service,@Component, etc.)
- Ensure the annotated method is
-
Redis connection is not configured
-
Fail-open is enabled and Redis is down
Redis connection errors
Redis connection errors
Symptoms:
io.lettuce.core.RedisConnectionException- Application fails to start
- Rate limit checks fail with connection errors
-
Verify Redis is running
-
Check Redis configuration
-
Start Redis locally with Docker
-
Enable fail-open for development
-
Check network connectivity
HTTP 429 not returning proper response
HTTP 429 not returning proper response
Symptoms:
- Exception is thrown but no HTTP 429 response
- Generic 500 error instead of 429
- Missing rate limit headers
-
Exception handler is not registered
- The starter auto-configures
RateLimitExceptionHandlerfor Spring MVC - Verify you’re using Spring Boot 3.x with servlet support
- Check that
@ControllerAdviceis not disabled
- The starter auto-configures
-
Custom exception handler overrides default
- If you have a custom
@ControllerAdvice, ensure it doesn’t catchRateLimitExceededException - Or handle it explicitly:
- If you have a custom
-
Headers are disabled
-
Using reactive/WebFlux
- The current version only supports Spring MVC (servlet)
- WebFlux support requires custom exception handling
Rate limits not working per-user
Rate limits not working per-user
Symptoms:
- All users share the same rate limit
- Different users get blocked together
- Rate limit doesn’t distinguish between users
-
Default key resolver doesn’t extract user context
- The default resolver uses
scope:className#methodName - Implement a custom
RateLimitKeyResolver:
- The default resolver uses
-
Key resolver not specified in annotation
-
User ID not available in method arguments
- Ensure the user identifier is passed as a method parameter
- Or extract it from Spring Security context in your resolver
-
Scope is set to GLOBAL
- Using
scope = "GLOBAL"creates a shared limit - Change to
scope = "USER"or custom scope
- Using
Metrics not appearing in Prometheus/Grafana
Metrics not appearing in Prometheus/Grafana
Symptoms:
- Rate limiter metrics not visible
- No
ratelimiter.*metrics in/actuator/prometheus
-
Metrics are disabled
-
Micrometer not on classpath
-
Actuator endpoints not exposed
-
No rate limit requests have been made
- Metrics only appear after at least one rate-limited request
- Trigger some requests to populate metrics
-
Check metric names
ratelimiter.requests(counter, tagged withoutcome=allowed|blocked)ratelimiter.errors(counter)ratelimiter.evaluate.latency(timer)
High latency on rate-limited methods
High latency on rate-limited methods
Symptoms:
- Slow response times on annotated methods
- Redis operations taking too long
-
Redis server is overloaded or slow
- Check Redis metrics:
redis-cli info stats - Consider scaling Redis or using Redis cluster
- Check Redis metrics:
-
Network latency to Redis
- Use Redis in the same region/data center
- Increase connection pool size:
-
Timeout is too high
-
Too many Redis keys
- Use shorter rate limit windows
- Implement key expiration strategy
- Monitor Redis memory usage
Redis keys accumulating and not expiring
Redis keys accumulating and not expiring
Symptoms:
- Redis memory usage keeps growing
- Rate limit keys not being cleaned up
-
Check key TTL
-
TTL not being set properly
- This is handled automatically by the starter
- Check for Redis version compatibility (Redis 2.6+)
-
Configure maxmemory policy
-
Manual cleanup if needed
Integration tests fail with 'Cannot connect to Docker'
Integration tests fail with 'Cannot connect to Docker'
Symptoms:
org.testcontainers.containers.ContainerLaunchException- Tests fail with Docker connection errors
-
Docker is not running
-
Run tests without integration tests
-
Configure Testcontainers
-
Use @Testcontainers(disabledWithoutDocker = true)
Rate limit resets unexpectedly
Rate limit resets unexpectedly
Symptoms:
- Rate limit counter resets before window expires
- Inconsistent rate limiting behavior
-
Application restarts
- Redis keys persist across restarts
- But in-memory state is lost
-
Redis restart or failover
- Keys are lost if Redis has no persistence
- Enable RDB or AOF persistence
-
Key name changes
- Changing class names, method names, or key resolver logic creates new keys
- Old keys will expire naturally
-
Redis eviction policy
- Check
maxmemory-policysetting - Use
volatile-lruorallkeys-lru
- Check
-
Clock skew
- Ensure system clocks are synchronized (NTP)
- Redis and app servers should have consistent time