spring-cloud / spring-cloud/spring-cloud-gateway

Multiple RetryGatewayFilterFactorys conflict on retry_iteration

Open
#3,773 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

waiting-for-triage
Dominant language
Java
Stars
4.9k
Forks
3.5k
Avg merge
20h 57m
Merged PRs (30d)
8

Description

Is your feature request related to a problem? Please describe.
I have a need to configure multiple Retry filters in the default-filters for a few reasons.

  1. I dont want to retry POST/DELETE operations if the first call times out, but I do for other operations
  2. We have downstream systems that sometimes return 500 and on retry they succeed, so I want to retry on 500 response just once but on 503 or timeouts (in some cases) I want to retry multiple times.

The above is not possible in a clean solution as all the retry filters share the attribute retry_iteration so if I have enough retry filters configured, its possible for a retry filter to show that it exceeded max iterations when it did not. This can also make it so that a specific call is not retried as many times as it should be.

And the logs dont make it clear all the time which of the multiple retry filters is running:

04/16/25 09:05:42 d218c-5c79-4df9-b883-944e588d4 TRACE factory.RetryGatewayFilterFactory: Entering retry-filter 04/16/25 09:05:42 d218c-5c79-4df9-b883-944e588d4 TRACE factory.RetryGatewayFilterFactory: Entering retry-filter 04/16/25 09:05:42 d218c-5c79-4df9-b883-944e588d4 TRACE factory.RetryGatewayFilterFactory: Entering retry-filter 04/16/25 09:05:42 d218c-5c79-4df9-b883-944e588d4 TRACE factory.RetryGatewayFilterFactory: Entering retry-filter 04/16/25 09:05:42 d218c-5c79-4df9-b883-944e588d4 TRACE factory.RetryGatewayFilterFactory: Entering retry-filter

Describe the solution you'd like
In my use-case, the retry filters cannot share retry_iteration so either a sequence (order of retry filters), a name/id for each configured Retry filter need to be appended to the attribute key used (ex: retry_iteration_1 or retry_iteration_<name/id>) so that each retry filter has its own value. The name/id solution could also help with the logs that get printed to understand which filters are executing because right now it looks like below:

04/16/25 09:31:23 b0064-3b42-45eb-a7d6-80e4e7354 TRACE factory.RetryGatewayFilterFactory: Entering retry-filter 04/16/25 09:31:23 b0064-3b42-45eb-a7d6-80e4e7354 TRACE factory.RetryGatewayFilterFactory: Entering retry-filter 04/16/25 09:31:23 b0064-3b42-45eb-a7d6-80e4e7354 TRACE factory.RetryGatewayFilterFactory: Entering retry-filter 04/16/25 09:31:23 b0064-3b42-45eb-a7d6-80e4e7354 TRACE factory.RetryGatewayFilterFactory: Entering retry-filter

This is what I want my retry filters to look like:

  • name: Retry
    args:
    retries: 5
    series:
    statuses: BAD_GATEWAY, SERVICE_UNAVAILABLE
    methods:
    - GET
    - PUT
    - PATCH
    - name: Retry
    args:
    retries: 5
    series:
    statuses: BAD_GATEWAY, SERVICE_UNAVAILABLE
    methods:
    - POST
    - DELETE
    exceptions:
    - java.io.IOException # dont retry on timeouts
    ## Retry only once on 500 error
    - name: Retry
    args:
    retries: 1
    series:
    statuses: INTERNAL_SERVER_ERROR
    methods:
    - GET
    - PUT
    - PATCH
    - name: Retry
    args:
    retries: 1
    series:
    statuses: INTERNAL_SERVER_ERROR
    methods:
    - POST
    - DELETE
    exceptions:
    - java.io.IOException

Describe alternatives you've considered
I dont want to configure the retry filter on each route

Additional context
None

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at RetryGatewayFilterFactory and trace how the shared retry_iteration attribute is used when multiple default Retry filters run. Inspect the existing retry configuration and trace logging around that entry point. Done means multiple filters maintain independent retry limits and the logs distinguish which filter is executing without breaking the requested method, status, and exception behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
java, spring, spring-boot
Domain
api, backend
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.