- severity: High
- files:
shenyu-plugin/shenyu-plugin-fault-tolerance/shenyu-plugin-ratelimiter/src/main/resources/META-INF/scripts/concurrent_request_rate_limiter.lua:18-33; callback at .../algorithm/ConcurrentRateLimiterAlgorithm.java:59
- description: The concurrent lua does
zadd but the only setex line is commented out (-- redis.call("setex", key, timestamp) at line 32). Every other algorithm sets an explicit TTL. The concurrent limiter relies solely on the doFinally callback (opsForZSet().remove(...).subscribe()) to remove entries, and that call is fire-and-forget with no error handling. If the gateway crashes, the request errors before doFinally, or the Redis remove fails, the member stays in the zset forever.
- impact: A few lost cleanup callbacks permanently disable concurrency limiting for the affected key; no self-healing.
- suggested_fix: Add
redis.call("expire", key, <safety TTL>) in the lua; guard the callback subscribe with error logging.
- confidence: High
- related_existing: none
Identified during the 2026-08-02 deep re-scan; full list in docs/scan2-2026-08-02/00-consolidated-critical-high.md.
shenyu-plugin/shenyu-plugin-fault-tolerance/shenyu-plugin-ratelimiter/src/main/resources/META-INF/scripts/concurrent_request_rate_limiter.lua:18-33; callback at.../algorithm/ConcurrentRateLimiterAlgorithm.java:59zaddbut the onlysetexline is commented out (-- redis.call("setex", key, timestamp)at line 32). Every other algorithm sets an explicit TTL. The concurrent limiter relies solely on thedoFinallycallback (opsForZSet().remove(...).subscribe()) to remove entries, and that call is fire-and-forget with no error handling. If the gateway crashes, the request errors beforedoFinally, or the Redisremovefails, the member stays in the zset forever.redis.call("expire", key, <safety TTL>)in the lua; guard the callbacksubscribewith error logging.Identified during the 2026-08-02 deep re-scan; full list in
docs/scan2-2026-08-02/00-consolidated-critical-high.md.