I've an Azure Cache for Redis - Premium and Cluster enabled. I've been trying to connect to that Redis using spring-boot-starter-data-redis (spring boot version: 2.3.4.RELEASE, Java version: 11) and using lettuce client but Lettuce is throwing the following SSL exception when I am treating my Redis as a Redis Cluster but connects just fine when using it as a Standalone Redis server.
My pom.xml dependencies are:
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
        <exclusions>
            <exclusion>
                <groupId>org.junit.vintage</groupId>
                <artifactId>junit-vintage-engine</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
</dependencies>
Java code:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.*;
import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.StringRedisTemplate;
@Configuration
class LettuceConfig {
    @Bean
    StringRedisTemplate getStringRedisTemplate(final RedisProperties redisProperties) {
        return new StringRedisTemplate(getRedisConnectionFactory(redisProperties));
    }
    @Bean
    RedisConnectionFactory getRedisConnectionFactory(final RedisProperties redisProperties) {
    
        final RedisNode redisNode = RedisNode.newRedisNode()
                .listeningAt(redisProperties.getHost(), redisProperties.getPort())
                .build();
        // Connecting as a Redis Cluster
        final RedisClusterConfiguration redisClusterConfiguration = new RedisClusterConfiguration();
        redisClusterConfiguration.addClusterNode(redisNode);
        redisClusterConfiguration.setPassword(RedisPassword.of(redisProperties.getPassword()));
        // Connecting as a Standalone Redis server
        final RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
        redisStandaloneConfiguration.setHostName(redisProperties.getHost());
        redisStandaloneConfiguration.setPort(redisProperties.getPort());
        redisStandaloneConfiguration.setPassword(RedisPassword.of(redisProperties.getPassword()));
        final LettuceClientConfiguration.LettuceClientConfigurationBuilder lettuceClientConfigurationBuilder =
                LettuceClientConfiguration.builder()
                .clientName(redisProperties.getClientName())
                .commandTimeout(redisProperties.getTimeout());
        if (redisProperties.isSsl()) {
            lettuceClientConfigurationBuilder.useSsl();
        }
        final LettuceClientConfiguration lettuceClientConfiguration = lettuceClientConfigurationBuilder.build();
        return new LettuceConnectionFactory(redisClusterConfiguration, lettuceClientConfiguration);
    }
}
@SpringBootApplication
public class LettuceClusterApplication implements CommandLineRunner {
    private final StringRedisTemplate stringRedisTemplate;
    @Autowired
    public LettuceClusterApplication(final StringRedisTemplate stringRedisTemplate) {
        this.stringRedisTemplate = stringRedisTemplate;
    }
    public static void main(String[] args) {
        SpringApplication.run(LettuceClusterApplication.class, args);
    }
    @Override
    public void run(String... args) throws Exception {
        System.out.println(stringRedisTemplate.hasKey("abc"));
    }
}
When using redisStandaloneConfiguration in new LettuceConnectionFactory(..., ...), the code works just fine, but if I use redisClusterConfiguration, the code fails with the following exception:
java.lang.IllegalStateException: Failed to execute CommandLineRunner
    at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:798) ~[spring-boot-2.3.4.RELEASE.jar:2.3.4.RELEASE]
    ...
Caused by: org.springframework.data.redis.RedisConnectionFailureException: Redis connection failed; nested exception is io.lettuce.core.RedisConnectionException: Unable to connect to [RedisURI [host='<redacted>.redis.cache.windows.net', port=6380]]
    at org.springframework.data.redis.connection.lettuce.LettuceExceptionConverter.convert(LettuceExceptionConverter.java:66) ~[spring-data-redis-2.3.4.RELEASE.jar:2.3.4.RELEASE]
    ...
Caused by: io.lettuce.core.RedisConnectionException: Unable to connect to [RedisURI [host='<redacted>.redis.cache.windows.net', port=6380]]
    at io.lettuce.core.RedisConnectionException.create(RedisConnectionException.java:78) ~[lettuce-core-5.3.4.RELEASE.jar:5.3.4.RELEASE]
    ...
Caused by: javax.net.ssl.SSLHandshakeException: No subject alternative names matching IP address <redacted> found
    ...
Caused by: java.security.cert.CertificateException: No subject alternative names matching IP address <redacted> found
    at java.base/sun.security.util.HostnameChecker.matchIP(HostnameChecker.java:165) ~[na:na]
    ...
My application.properties file:
spring.redis.host = <redacted>.redis.cache.windows.net
spring.redis.port = 6380
spring.redis.password = <redacted>
spring.redis.ssl = true
spring.redis.clientName = ${HOSTNAME}
spring.redis.timeout = 100000
Update: Found a similar issue in Github: https://github.com/lettuce-io/lettuce-core/issues/246 but it says that it should work with lettuce versions > 4.2 and my lettuce-core version (bundled under spring-boot-starter-data-redis) is 5.3.4.RELEASE.
Also worth checking out is the documentation which states the same: https://lettuce.io/core/release/reference/#ssl
Lettuce supports SSL connections since version 3.1 on Redis Standalone connections and since version 4.2 on Redis Cluster
Raised GitHub issue as well: https://github.com/lettuce-io/lettuce-core/issues/1454
                        
We got the following error when just using
spring.data.redis.ssl.enabled=true.After some trial and error we changed from lettuce (which is the default library to talk with redis in Spring Boot) to jedis and then it worked :)
We did that with the following code in pom.xml:
We are using Spring Boot 3.1.5 and java 21.