Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Default backoff doesn't honour RetryWaitMax when "Retry-After" header is sent in the response #247

Open
Hemanthk1099 opened this issue Dec 19, 2024 · 1 comment

Comments

@Hemanthk1099
Copy link

Hemanthk1099 commented Dec 19, 2024

go-retryablehttp/client.go

Lines 551 to 566 in 9dfd949

func DefaultBackoff(min, max time.Duration, attemptNum int, resp *http.Response) time.Duration {
if resp != nil {
if resp.StatusCode == http.StatusTooManyRequests || resp.StatusCode == http.StatusServiceUnavailable {
if sleep, ok := parseRetryAfterHeader(resp.Header["Retry-After"]); ok {
return sleep
}
}
}
mult := math.Pow(2, float64(attemptNum)) * float64(min)
sleep := time.Duration(mult)
if float64(sleep) != mult || sleep > max {
sleep = max
}
return sleep
}

The DefaultBackoff in function has a logical flaw when handling the Retry-After header. If the server provides an unreasonably high value in the Retry-After header, the function respects it without enforcing the RetryWaitMax limit set for the httpClient. This can lead to indefinite wait times or blocking behaviour.

Steps to Reproduce

  1. Simulate a server response with an HTTP 429 Too Many Requests status.
  2. Set a high value in the Retry-After header (e.g., Retry-After: 3600 for 1 hour).
  3. Observe that the backoff duration exceeds the configured RetryWaitMax limit.

Expected Behaviour

I believe the backoff duration should always be bounded by the configured RetryWaitMax value, regardless of the Retry-After header value.

Suggested Fix

Honour "Retry-After" header value only if its less than or equal to RetryWaitMax in default retry strategy

if sleep <= max {
    return max // Enforce max backoff limit
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant