Repository navigation
Labels
type: bugA general bugA general bug
Description
Bug Report
Current Behavior
IllegalStateExceptions are being thrown when trying to establish connections to redis with a username/password since Lettuce 7 when using Spring WebFlux.
Stack trace
block()/blockFirst()/blockLast() are blocking, which is not supported in thread reactor-http-nio-3
reactor.core.publisher.BlockingSingleSubscriber.blockingGet(BlockingSingleSubscriber.java:87)
reactor.core.publisher.Mono.block(Mono.java:1779)
io.lettuce.core.RedisURI.getAuthority(RedisURI.java:951)
io.lettuce.core.RedisURI.createUriString(RedisURI.java:812)
io.lettuce.core.RedisURI.toString(RedisURI.java:1070)
io.lettuce.core.ConnectionBuilder.apply(ConnectionBuilder.java:115)
io.lettuce.core.AbstractRedisClient.connectionBuilder(AbstractRedisClient.java:252)
io.lettuce.core.cluster.RedisClusterClient.createConnectionBuilder(RedisClusterClient.java:901)
io.lettuce.core.cluster.RedisClusterClient.connectStatefulAsync(RedisClusterClient.java:869)
io.lettuce.core.cluster.RedisClusterClient.connectToNodeAsync(RedisClusterClient.java:563)
….core.cluster.PooledClusterConnectionProvider$DefaultClusterNodeConnectionFactory.apply(PooledClusterConnectionProvider.java:801)
….core.cluster.PooledClusterConnectionProvider$DefaultClusterNodeConnectionFactory.apply(PooledClusterConnectionProvider.java:775)
….lettuce.core.cluster.PooledClusterConnectionProvider$NodeConnectionPostProcessor.apply(PooledClusterConnectionProvider.java:741)
….lettuce.core.cluster.PooledClusterConnectionProvider$NodeConnectionPostProcessor.apply(PooledClusterConnectionProvider.java:712)
io.lettuce.core.internal.AsyncConnectionProvider.lambda$getSynchronizer$0(AsyncConnectionProvider.java:85)
java.base/java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1708)
io.lettuce.core.internal.AsyncConnectionProvider.getSynchronizer(AsyncConnectionProvider.java:83)
io.lettuce.core.internal.AsyncConnectionProvider.getConnection(AsyncConnectionProvider.java:60)
io.lettuce.core.cluster.PooledClusterConnectionProvider.getConnectionAsync(PooledClusterConnectionProvider.java:461)
io.lettuce.core.cluster.PooledClusterConnectionProvider.getReadFromConnections(PooledClusterConnectionProvider.java:411)
io.lettuce.core.cluster.PooledClusterConnectionProvider.getReadConnection(PooledClusterConnectionProvider.java:262)
io.lettuce.core.cluster.PooledClusterConnectionProvider.getConnectionAsync(PooledClusterConnectionProvider.java:152)
io.lettuce.core.cluster.ClusterDistributionChannelWriter.doWrite(ClusterDistributionChannelWriter.java:182)
io.lettuce.core.cluster.ClusterDistributionChannelWriter.write(ClusterDistributionChannelWriter.java:116)
io.lettuce.core.RedisChannelHandler.dispatch(RedisChannelHandler.java:203)
io.lettuce.core.cluster.StatefulRedisClusterConnectionImpl.dispatch(StatefulRedisClusterConnectionImpl.java:247)
...Input Code
Creating the RedisURI with a username and password is causing this code to run on connect which is calling the .block() method:
| RedisCredentials creds = credentialsProvider.resolveCredentials().block(); |
Input Code
RedisURI redisURI = RedisURI.builder()
.withHost(clusterConfigEndpoint)
.withAuthentication(redisUsername, redisPassword)
.withSsl(true)
.build();Expected behavior/code
There should be no calls to .block() when establishing the connection. This is causing reactor threads to throw exceptions.
Environment
- Lettuce version(s): 7.2.1.RELEASE
- Redis version: Valkey 8.1
Possible Solution
Remove the .block() call in the RedisURI.getAuthority method.
Metadata
Metadata
Assignees
Labels
type: bugA general bugA general bug
Activity
PreAgile commentedon Mar 30, 2026
Hi, I'd like to work on this issue.
It looks like the .block() in RedisURI.getAuthority() is the cause here. I'll investigate a non-blocking fix
that preserves existing behavior and add a regression test. Let me know if there are any caveats I should be
aware of before I start.
young0264 commentedon May 15, 2026
Hi @tishun,
This looks like a blocking call is being introduced during
RedisURIstring/authority materialization in the connection setup path.From the stack trace, what stands out to me is:
ConnectionBuilder.apply(...)callsredisURI.toString()RedisURI.toString()goes through the masking pathRedisURI.getAuthority()appears to resolve credentials via.block()That seems consistent with the
IllegalStateExceptionshowing up when a new connection is created on a Reactor thread with username/password authentication configured.I previously contributed a related Lettuce change around moving DNS resolution onto the non-blocking path, so I’d be happy to take a closer look at this one as well.
If this understanding matches the intended behavior, I can work on a fix and open a PR.
Feel free to assign it to me if that works for you.
tishun commentedon May 21, 2026
FWIW @a-TODO-rov is currently maintaining the driver.
@PreAgile and @young0264 please sync between each other - you can both work on the task if you want to, just send a PR when you are ready.
young0264 commentedon May 21, 2026
Hi @PreAgile!
Since you expressed interest in this issue first, I wanted to check with you before starting on my side.
It looks like the maintainer is okay with moving forward on this issue. If you're planning to work on it, please feel free to take it and open a PR first.
If you haven't started yet or don't have enough time to continue, I can take a first pass and open a PR. I'm also happy to collaborate on the fix or help review/test the PR if needed.
Could you let me know how you'd like to proceed?
Thanks!
안녕하세요 @PreAgile님, 한국어로도 간단히 남깁니다.
먼저 이슈에 관심을 표현해주셔서, 제가 작업을 시작하기 전에 먼저 의사를 여쭤보고 싶었습니다.
진행하실 계획이 있으시면 먼저 PR을 올려주셔도 좋고, 아직 시작 전이시거나 시간이 부족하시다면 제가 먼저 작업해보겠습니다.
필요하다면 수정 방향이나 테스트 쪽에서 같이 협업해도 좋을 것 같습니다.
감사합니다!
a-TODO-rov commentedon May 21, 2026
We should keep in mind, that this will be fixed with #3614 and you can actually see it being addressed here .
However this changes will probably take effect from 8.0 forward and we should think about a solution for 7.x branch as well.
So if you have some proposals on that one, i will be glad to review them.
PreAgile commentedon May 25, 2026
PR #3762 is up. @young0264 — would love your review on the test cases in particular (the reactor-parallel scheduler regression test is the one I'd most want a second pair of eyes on). If you spot a different approach you'd prefer, very open to iterating on the PR before it's marked ready.
young0264 commentedon May 26, 2026
Hi @PreAgile,
I opened a small PR against your fork with additional test coverage for #3762: PreAgile#1
It covers a few extra RedisURI masking scenarios around immediate/non-immediate credential providers.
Please feel free to take whichever parts make sense for #3762.
Thanks!
a-TODO-rov commentedon May 26, 2026
Left review
Mask RedisURI credentials without Mono#block()