redis/jedis · critical · JedisConnectionException
The connection to ' ' failed ssl/tls hostname verification.
Error message
The connection to '${_hostAndPort.getHost()}' failed ssl/tls hostname verification. What it means
After Jedis wraps the plain socket in an SSL socket, it runs the configured HostnameVerifier against the server certificate's session. If the certificate does not match the host in the HostAndPort used for the connection, it throws JedisConnectionException with 'The connection to <host> failed ssl/tls hostname verification.' This prevents man-in-the-middle attacks where a valid certificate is presented for a different name.
Solutions
- Use the exact hostname the server certificate was issued for in the client's HostAndPort configuration.
- Fix the server certificate: reissue it with SANs covering the hostnames/IPs clients actually connect to.
- Provide a custom SslOptions/HostnameVerifier only if you can verify identity another way (e.g. certificate pinning) — never disable verification in production.
- Check for hostname mismatch caused by DNS aliases or load balancers and align cert SANs with those names.
- Test with 'openssl s_client -connect host:port -servername host' to inspect the served certificate.
Example fix
// before
Jedis jedis = new Jedis(HostAndPort.from("10.0.0.5:6380"),
DefaultJedisClientConfig.builder().ssl(true).build()); // cert is for redis.example.com
// after
Jedis jedis = new Jedis(HostAndPort.from("redis.example.com:6380"),
DefaultJedisClientConfig.builder().ssl(true).build()); // hostname matches cert Defensive patterns
Strategy: validation
Validate before calling
// verify the server cert covers the host before connecting
import javax.net.ssl.*;
SSLContext ctx = SSLContext.getDefault();
SSLSocketFactory f = ctx.getSocketFactory();
try (SSLSocket s = (SSLSocket) f.createSocket(host, port)) {
s.startHandshake();
if (!HttpsURLConnection.getDefaultHostnameVerifier().verify(host, s.getSession())) {
throw new IllegalStateException("Cert does not match host " + host);
}
} Try / catch
try {
jedis = new Jedis(hostAndPort, sslConfig);
} catch (JedisConnectionException e) {
if (e.getMessage() != null && e.getMessage().contains("hostname verification")) {
// align HostAndPort hostname with the certificate SANs, or reissue the cert
}
throw e;
} Prevention
- Connect using the hostname on the certificate, never bare IPs or unlisted internal aliases.
- Issue server certs with SANs covering every hostname/IP clients use (including load balancer names).
- Only customize HostnameVerifier for verified internal PKI setups; never return true unconditionally.
- Use SslOptions to supply a trust store pinning your CA instead of weakening hostname checks.
- Audit cert expirations and SAN coverage as part of TLS rotation.
When it happens
Trigger: Connecting with ssl=true (or SslOptions) to a server whose TLS certificate CN/SAN does not match the hostname used in the client configuration — e.g. connecting via an IP address, 'localhost', a load balancer/CNAME, or a hostname spelled differently from the certificate; or supplying a restrictive custom HostnameVerifier.
Common situations: Pointing the client at a proxy/load balancer whose cert covers a different name; using IP addresses or service internal names (e.g. k8s pod names) not in the cert SANs; self-signed or internally-issued certs; renaming hosts after cert issuance; migrating from plaintext to TLS without updating certs.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- SSL configuration failed
- Failed to create input/output stream
- Attempting to write to a broken connection.
- Attempting to read from a broken connection.
- Failed to create socket.
AI-assisted analysis of redis/jedis@6dac31d4c2 (2026-09-08).
Data as JSON: /api/errors/9f6ebe84db70c9db.
Report an issue: GitHub.
Appendix: source
Thrown at src/main/java/redis/clients/jedis/DefaultJedisSocketFactory.java:181
}
SSLSocket sslSocket = (SSLSocket) _sslSocketFactory.createSocket(socket,
_hostAndPort.getHost(), _hostAndPort.getPort(), true);
// Enable hostname verification by default (HTTPS algorithm).
// Users can override by providing custom SSLParameters via JedisClientConfig.
if (_sslParameters == null) {
_sslParameters = new SSLParameters();
_sslParameters.setEndpointIdentificationAlgorithm("HTTPS");
}
sslSocket.setSSLParameters(_sslParameters);
// allowing HostnameVerifier for both SslOptions and legacy ssl config
if (hostnameVerifier != null && !hostnameVerifier.verify(_hostAndPort.getHost(), sslSocket.getSession())) {
String message = String.format("The connection to '%s' failed ssl/tls hostname verification.",
_hostAndPort.getHost());
throw new JedisConnectionException(message);
}
return new SSLSocketWrapper(sslSocket, plainSocket);
}
public void updateHostAndPort(HostAndPort hostAndPort) {
this.hostAndPort = hostAndPort;
}
public HostAndPort getHostAndPort() {
return this.hostAndPort;
}
protected HostAndPort getSocketHostAndPort() {
HostAndPortMapper mapper = hostAndPortMapper;
HostAndPort hap = this.hostAndPort;
if (mapper != null) {
HostAndPort mapped = mapper.getHostAndPort(hap);View on GitHub (pinned to 6dac31d4c2)