envoyproxy / envoyproxy/gateway
rate-limit translator emits a listener-domain filter even when no listener-level rules exist, doubling the rate limit request
- Dominant language
- Go
- Stars
- 3k
- Forks
- 864
- Avg merge
- 2d 2h
- Merged PRs (30d)
- 140
Description
Description
Envoy Gateway's rate-limit translator unconditionally emits a RateLimit HTTP filter with domain set to the listener name, even when no listener-level rate-limit rules exist. This filter then runs in addition to the per-BackendTrafficPolicy filters created from BackendTrafficPolicy.spec.rateLimit.global.rules with shared: true.
Both filters are at the default stage: 0 and operate on the same route-level rate_limits actions, so every customer request results in two sequential RLS calls — one with the listener-name domain (which has no rules loaded on the RLS side, always returns "OK"), and one with the BackendTrafficPolicy-name domain (the actual rate-limit decision).
Expected: only one filter (the BTP-domain one) should be emitted when there are no listener-level rate-limit rules. The listener-domain filter has nothing to evaluate against and should be skipped.
The redundant filter appears to be added unconditionally here in the translator:
// internal/xds/translator/ratelimit.go
domains.Insert(irListener.Name) // ← always added
domains.Insert(stripRuleIndexSuffix(rule.Name)) // ← per-shared-rule
Each entry in domains is then turned into its own RateLimit filter via createRateLimitFilter. With one BackendTrafficPolicy that has only shared: true rules, this produces 2 filters where 1 would suffice.
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.