Skip to content

StackOverflowError in DefaultedRedisConnection.set on 4.1.0 (regression from 4.0.6) #3391

Description

@jpbassinello

Summary

Upgrading spring-data-redis from 4.0.6 to 4.1.0 (via the Spring Boot 4.0.6 → 4.1.0 BOM bump) causes a StackOverflowError inside DefaultedRedisConnection on RedisConnection.set(...) calls. Reverting to 4.0.6 resolves it immediately with no other code changes.

Environment

  • spring-data-redis: 4.1.0 (regression), 4.0.6 (last known-good)
  • Spring Boot: 4.1.0
  • Redis client: Lettuce (default LettuceConnectionFactory)
  • Trigger path: org.springframework.cache.CacheManager (Redis-backed) → RedisCache.putRedisConnection.set(...), invoked here via a Camel SpringCacheIdempotentRepository write, but any Redis-backed @Cacheable/cache-put should reproduce it

Stack trace (prod, truncated — ~994 identical frames)

java.lang.StackOverflowError: null
	at org.springframework.data.redis.connection.DefaultedRedisConnection.set(DefaultedRedisConnection.java:374)
	at org.springframework.data.redis.connection.DefaultedRedisConnection.set(DefaultedRedisConnection.java:374)
	... (repeats)

What we found comparing bytecode across releases

Decompiling DefaultedRedisConnection, RedisConnection, and RedisStringCommands from the published 4.0.5, 4.0.6, and 4.1.0 jars:

  • 4.0.5 and 4.0.6 are byte-for-byte identical for DefaultedRedisConnection and RedisConnection — no regression between those two.
  • Going from 4.0.6 → 4.1.0, RedisStringCommands changes:
    • set(byte[], byte[], Expiration, SetOption) / setGet(byte[], byte[], Expiration, SetOption) are replaced by new overloads taking SetCondition instead: set(byte[], byte[], SetCondition, Expiration) / setGet(byte[], byte[], SetCondition, Expiration).
    • New default methods appear: digest, delex, xDelEx, xAckDel, xTrim.
  • We were not able to pin down the exact recursive pair from bytecode alone (the published jars ship without debug/line-number tables, so we can't map the stack trace's line 374 to a specific overload). Given the timing, our working theory is that the set/setGet overload swap introduced a default-method cycle in DefaultedRedisConnection — e.g. one overload's default implementation now delegates to the other overload's default implementation, which delegates back — but this needs confirmation against the actual 4.1.0 source.

Impact

In our case this crashed a production financial-services payments pipeline (Redis-backed idempotent-write cache used in an Apache Camel SFTP polling route) — every scheduled poll thread died with this error for ~2.5 hours before we identified the Boot/spring-data-redis version bump as the cause and rolled it back.

Workaround

Pin spring-data-redis back to 4.0.6 while keeping Spring Boot on 4.1.0 (override the BOM-managed version). No other code changes needed to avoid the crash.

Ask

Could someone confirm whether this is a known issue with the set/setGet SetCondition refactor in 4.1.0, and whether a patch release is planned? Happy to provide a minimal reproduction if useful.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions