CVE-2026-41710

Denial of Service
Affects
Spring Retry
in
Spring
No items found.
Versions
>=1.3.0 <=1.3.4, >=2.0.0 <=2.0.12
Exclamation circle icon
Patch Available

This Vulnerability has been fixed in the Never-Ending Support (NES) version offered by HeroDevs.

Overview

Spring Retry is a Java library that provides declarative and programmatic retry support for Spring applications, letting callers automatically re-invoke an operation that has failed transiently. It backs the @Retryable annotation, the RetryTemplate API, and circuit-breaker functionality, and is used both directly and as a transitive dependency across the Spring ecosystem.

A medium-severity vulnerability (CVE-2026-41710) has been identified in Spring Retry's stateful retry support. When stateful retries are enabled, Spring Retry stores per-attempt state in an application-wide retry-context cache (MapRetryContextCache). That cache is backed by a plain HashMap with a hard capacity bound (DEFAULT_CAPACITY = 4096) and no eviction. When the cache key is derived from attacker-controllable request input, an attacker can craft a large number of unique requests that trigger a failure, each of which inserts a new entry into the shared cache. Abandoned failing entries persist until the operation either succeeds or exhausts its retry policy, so they occupy cache slots indefinitely. Once the cache reaches capacity, MapRetryContextCache.put() throws RetryCacheCapacityExceededException and no further entries can be added, denying retry and circuit-breaker state to all subsequent callers, including legitimate ones.

Per OWASP, a Denial of Service (DoS) attack is focused on making a resource (site, application, server) unavailable for the purpose it was designed; there are many ways to make a service unavailable for legitimate users by manipulating network packets, programming, logical, or resource-handling vulnerabilities, among others. Exhausting the shared retry-context cache with attacker-seeded failing keys is a resource-handling instance of this class: a bounded, non-evicting cache is filled until it can no longer admit new entries.

This issue affects versions 1.3.0 through 1.3.4 and 2.0.0 through 2.0.12 of Spring Retry.

Details

Module Info

Vulnerability Info

The vulnerability is in org.springframework.retry.policy.MapRetryContextCache, the default RetryContextCache implementation used to hold per-key retry state during stateful retries.

An application is exposed when all of the following are true:

  • Stateful retries are explicitly enabled, for example @Retryable(stateful = true), a stateful RetryState, or a circuit-breaker configuration.
  • The cache key is attacker-controllable, that is, derived from request input.
  • The attacker can cause the guarded invocation to fail.

Under those conditions, every unique failing request seeds a new entry in the application-wide cache. Entries are only removed when the corresponding operation succeeds or its retry policy is exhausted, so a flood of distinct, abandoned failing requests fills the cache and never releases the slots.

Prior to the fix, MapRetryContextCache.put() was backed by a plain HashMap and threw when full, with no eviction:

public static final int DEFAULT_CAPACITY = 4096;

private final Map<Object, RetryContext> map = Collections.synchronizedMap(new HashMap<>());

public void put(Object key, RetryContext context) {
    if (map.size() >= capacity) {
        throw new RetryCacheCapacityExceededException("Retry cache capacity limit breached. "
                + "Do you need to re-consider the implementation of the key generator, "
                + "or the equals and hashCode of the items that failed?");
    }
    map.put(key, context);
}

Two properties of this implementation make the denial of service possible. First, the map has a hard ceiling and no eviction policy, so once it reaches capacity it stays full and rejects all new keys permanently. Second, regular stateful retries and circuit-breaker state share a single fail-fast cache instance, so exhaustion caused by one path poisons the other. The shared, non-evicting cache is the denial-of-service surface: attacker-seeded entries it can never reclaim block legitimate callers from registering retry state.

Mitigation

The 1.3.x line of Spring Retry is End-of-Life and the affected releases do not receive further OSS security fixes. Older versions have no publicly available fix for this vulnerability outside of the noted releases.

Users of the affected versions should apply one of the following mitigations:

  • Upgrade to a currently supported version of Spring Retry. The OSS fix ships in Spring Retry 2.0.13; commercial-support backports are available as 2.0.12.1 and 1.3.5.
  • Leverage a commercial support partner like HeroDevs for post-EOL security support through Never-Ending Support (NES) for Spring Retry.

Credits

  • No external reporter was credited for this issue.
Vulnerability Details
Severity
Level
CVSS Assessment
Low
>=0 <4
Medium
>=4 <6
High
>=6 <8
Critical
>=8 <10
Medium
ID
CVE-2026-41710
PROJECT Affected
Spring Retry
Versions Affected
>=1.3.0 <=1.3.4, >=2.0.0 <=2.0.12
NES Versions Affected
Published date
June 11, 2026
≈ Fix date
June 11, 2026
Category
Denial of Service
Vex Document
Download VEXHow do I use it?
Sign up for the latest vulnerability alerts fixed in
NES for Spring
Rss feed icon
Subscribe via RSS
or

By clicking “submit” I acknowledge receipt of our Privacy Policy.

Thanks for signing up for our Newsletter! We look forward to connecting with you.
Oops! Something went wrong while submitting the form.