The issue is that 'TimeoutException' is not being handled through the 'retryWhen' function.

I have this below usage of webclient

   someWebClient
                .post()
                .uri(requestUri)
                .contentType(MediaType.APPLICATION_JSON)
                .headers(headers -> headers.addAll(httpHeaders))
                .accept(MediaType.APPLICATION_JSON)
                .body(Mono.just(userRequest), UserRequest.class)
                .retrieve()
                .bodyToMono(UserResponse.class)
                .retryWhen(
                        Retry.backoff(
                                        userConfiguration.getNumRetries(),
                                        userConfiguration.getBackOff())
                                .maxBackoff(userConfiguration.getMaxBackOff())
                                .jitter(0.5)
                                .maxAttempts(100)
                                .filter(this::shouldRetry))
                .timeout(userConfiguration.getTimeout()); 

The shouldRetry method looks like this ,

private boolean shouldRetry(Throwable throwable) {
        String t = throwable.getMessage();
        return throwable instanceof io.netty.handler.timeout.TimeoutException;
    }

Now when testing the scenario for retries if there is a timeout I set the userConfiguration.getTimeout() to a low value like 10ms.

What happens is the control never enters the 'shouldRetry' method. Instead it throws a general TimeoutException . The message I get is this ,

Caused by: java.util.concurrent.TimeoutException: Did not observe any item or terminal signal within 1000ms in 'retryWhen' (and no fallback has been configured)

Comment From: rstoyanchev

The timeout operator cancels the work of the chain upstream, and that should make it stop retrying as well. If you want the timeout to apply to an individual request, then it should be declared before retryWhen. Or otherwise, as it is now, it applies to the complete HTTP request, including all potential retries.

I'm closing this since it seems nothing related to WebClient itself, and the same could probably reproduced without it. In that sense it's more of a question for Project Reactor.