This version is still in development and is not considered stable yet. For the latest stable version, please use Spring Cloud Gateway 4.3.2!

Retry Filter

The Retry filter automatically selects the appropriate retry implementation based on what is available on the classpath:

  • If Spring Retry is on the classpath, the filter uses GatewayRetryFilterFunctions (based on Spring Retry) by default.

  • If Spring Retry is not on the classpath, the filter automatically uses FrameworkRetryFilterFunctions (based on the retry functionality in Spring Framework 7).

Spring Retry has been placed in maintenance-only mode. Once Spring Retry is no longer being maintained, the Retry filter will exclusively use the Framework retry implementation (FrameworkRetryFilterFunctions), and the Spring Retry-based implementation will be removed.
You can force the use of the Framework retry filter even when Spring Retry is on the classpath by setting spring.cloud.gateway.server.webmvc.use-framework-retry-filter=true in your configuration.

The Retry filter supports the following parameters:

  • retries: The number of retries that should be attempted.

  • methods: The HTTP methods that should be retried, represented by using org.springframework.http.HttpMethod.

  • series: The series of status codes to be retried, represented by using org.springframework.http.HttpStatus.Series.

  • exceptions: A list of thrown exceptions that should be retried.

  • cacheBody: A flag to signal if the request body should be cached. If set to true, the adaptCacheBody filter must be used to send the cached body downstream.

The following defaults are configured for Retry filter, if enabled:

  • retries: Three times

  • series: 5XX series

  • methods: GET method

  • exceptions: IOException, TimeoutException and RetryException

  • cacheBody: false

Setting cacheBody to true causes the gateway to read the whole body into memory. This should be used with caution.

The following listing configures a Retry filter:

application.yml
spring:
  cloud:
    gateway:
      mvc:
        routes:
        - id: retry_route
          uri: http://localhost:8080/flakey
          predicates:
          - Host=*.retry.com
          filters:
          - name: Retry
            args:
              retries: 3
              series: SERVER_ERROR
              methods: GET,POST
              cacheBody: true
          - name: AdaptCachedBody
GatewaySampleApplication.java
import static org.springframework.cloud.gateway.server.mvc.filter.BeforeFilterFunctions.uri;
import static org.springframework.cloud.gateway.server.mvc.filter.FilterFunctions.adaptCachedBody;
import static org.springframework.cloud.gateway.server.mvc.filter.RetryFilterFunctions.retry;
import static org.springframework.cloud.gateway.server.mvc.handler.GatewayRouterFunctions.route;
import static org.springframework.cloud.gateway.server.mvc.handler.HandlerFunctions.http;
import static org.springframework.cloud.gateway.server.mvc.predicate.GatewayRequestPredicates.host;

@Configuration
class RouteConfiguration {

    @Bean
    public RouterFunction<ServerResponse> gatewayRouterFunctionsRetry() {
        return route("retry_route")
            .route(host("*.retry.com"), http())
            .before(uri("http://localhost:8080/flakey"))
            .filter(retry(config -> config.setRetries(3)
                    .setSeries(Set.of(HttpStatus.Series.SERVER_ERROR))
                    .setMethods(Set.of(HttpMethod.GET, HttpMethod.POST))
                    .setCacheBody(true)))
            .filter(adaptCachedBody())
            .build();
    }
}
When using the retry filter with a forward: prefixed URL, the target endpoint should be written carefully so that, in case of an error, it does not do anything that could result in a response being sent to the client and committed. For example, if the target endpoint is an annotated controller, the target controller method should not return ResponseEntity with an error status code. Instead, it should throw an Exception or signal an error (for example, through a Mono.error(ex) return value), which the retry filter can be configured to handle by retrying.
When using the retry filter, it will retry all filters that come after it. Make sure the results of the filters following the retry filter are as expected when they are executed multiple times.
When using the retry filter with any HTTP method with a body and cacheBody=true, the body will be cached and the gateway will become memory constrained. The body is cached in a request attribute defined by MvcUtils.CACHED_REQUEST_BODY_ATT. The type of the object is ByteArrayInputStream.

A simplified "shortcut" notation can be added with a single status and method.

The following two example routes are equivalent:

application.yml
spring:
  cloud:
    gateway:
      mvc:
        routes:
        - id: retry_route
          uri: https://example.org
          filters:
          - name: Retry
            args:
              retries: 3
              statuses: INTERNAL_SERVER_ERROR
              methods: GET
        - id: retryshortcut_route
          uri: https://example.org
          filters:
          - Retry=3,INTERNAL_SERVER_ERROR,GET

Forcing Framework Retry Filter

When Spring Retry is on the classpath, the Retry filter uses the Spring Retry-based implementation by default. To force the use of the Framework retry filter instead, set the following property:

application.yml
spring:
  cloud:
    gateway:
      server:
        webmvc:
          use-framework-retry-filter: true
application.properties
spring.cloud.gateway.server.webmvc.use-framework-retry-filter=true