envoyproxy/envoy

ratelimit/local_ratelimit: emit `Retry-After` header dynamically on 429 responses

Open

#45,384 opened on Jun 2, 2026

View on GitHub
 (5 comments) (4 reactions) (0 assignees)C++ (5,373 forks)batch import
area/local_ratelimitarea/ratelimitenhancementhelp wanted

Repository metrics

Stars
 (27,997 stars)
PR merge metrics
 (Avg merge 8d) (378 merged PRs in 30d)

Description

Description:

When either the global (envoy.filters.http.ratelimit) or local (envoy.filters.http.local_ratelimit) rate limit filter enforces a limit, it emits a 429 and optionally the IETF draft-03 header triple (x-ratelimit-limit, x-ratelimit-remaining, x-ratelimit-reset) if enable_x_ratelimit_headers: DRAFT_VERSION_03 is configured. However, neither filter emits Retry-After on 429 responses.

Retry-After on 429 is specified by RFC 6585 section 4, with the field format defined by RFC 9110 section 10.2.3 as an HTTP-date or delay-seconds integer. Both filter paths already compute the reset value needed to populate it. Only the emission is missing.

The existing response_headers_to_add field on both filter protos does not satisfy this: it accepts only static values and cannot express a value derived dynamically from rate limit state at request time.

Desired behaviour: add an opt-in flag to both filter protos — mirroring enable_x_ratelimit_headers — that causes the filter to emit Retry-After: <delay-seconds> on 429 responses only, with the value sourced dynamically from the most-restrictive matched rule's seconds-until-reset, clamped to ≥1.

Relevant Links:

Contributor guide