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.put → RedisConnection.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

Labels

status: invalidAn issue that we don't feel is valid

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions