redis/jedis · error · IOException

SSL configuration failed

Error message

SSL configuration failed

What it means

createConnection() configures TLS for HTTPS calls to the Redis Enterprise REST API. If building the SSLContext/TrustManager/HostnameVerifier setup throws GeneralSecurityException, it is wrapped in IOException("SSL configuration failed"). This is a client-side SSL setup problem, not a handshake failure.

Solutions

  1. Validate SslOptions: check keystore/truststore paths, passwords, and that the files load before calling the API
  2. Inspect the wrapped GeneralSecurityException cause for the exact crypto error
  3. Re-export the certificate in a standard format (PKCS12) and rebuild SslOptions
  4. Test SSL setup in isolation (load KeyStore/SSLContext directly) before configuring the client

Example fix

// before
SslOptions opts = SslOptions.builder().truststore("/path/typo.jks", "pass").build();
// after
SslOptions opts = SslOptions.builder()
    .truststore("/path/truststore.p12", "correctPassword")
    .trustStoreType("PKCS12")
    .build();
Defensive patterns

Strategy: validation

Validate before calling

try { KeyStore ks = KeyStore.getInstance("PKCS12"); ks.load(new FileInputStream(truststorePath), password); } catch (Exception e) { /* fail fast: bad SslOptions */ }

Type guard

boolean validSslOptions(SslOptions o) { return o != null && o.getSslVerifyMode() != null; } // plus load keystores eagerly at startup

Try / catch

try { api.bdbs(); } catch (IOException e) { if (e.getCause() instanceof GeneralSecurityException) { /* fix SslOptions */ } }

Prevention

When it happens

Trigger: Invalid keystore/truststore paths or formats, unsupported TLS algorithm names in the JVM, corrupted certificates supplied via SslOptions, or a JVM lacking the requested crypto provider.

Common situations: Misspelled truststore path or password; PKCS12 vs JKS confusion; custom SslOptions built with a bad KeyManagerFactory; restricted JCE policies on old JVMs.

Understand the failure class

Related errors


AI-assisted analysis of redis/jedis@6dac31d4c2 (2026-09-08). Data as JSON: /api/errors/faa74ca68fa9a278. Report an issue: GitHub.

Appendix: source

Thrown at src/main/java/redis/clients/jedis/mcf/RedisRestAPI.java:142

  HttpURLConnection createConnection(String urlString, String method, RedisCredentials credentials)
      throws IOException {
    URL url = new URL(urlString);
    HttpURLConnection connection = (HttpURLConnection) url.openConnection();

    // Configure SSL if this is an HTTPS connection and SSL options are provided
    if (connection instanceof HttpsURLConnection && sslOptions != null) {
      HttpsURLConnection httpsConnection = (HttpsURLConnection) connection;
      try {
        SSLContext sslContext = sslOptions.createSslContext();
        httpsConnection.setSSLSocketFactory(sslContext.getSocketFactory());

        if (sslOptions.getSslVerifyMode() == SslVerifyMode.CA
            || sslOptions.getSslVerifyMode() == SslVerifyMode.INSECURE) {
          httpsConnection.setHostnameVerifier((h, s) -> true); // skip hostname check
        }
      } catch (GeneralSecurityException e) {
        throw new IOException("SSL configuration failed", e);
      }
    }

    connection.setRequestMethod(method);
    connection.setConnectTimeout(timeoutMs);
    connection.setReadTimeout(timeoutMs);
    connection.setRequestProperty("Authorization", getAuthenticationHeader(credentials));

    return connection;
  }

  // This is just to avoid putting password chars directly into a string
  private static String getAuthenticationHeader(RedisCredentials credentials) throws IOException {
    // Build Basic auth without creating a password String
    final char[] pass = credentials.getPassword() != null ? credentials.getPassword() : new char[0];
    final String user = credentials.getUser() != null ? credentials.getUser() : "";
    final byte[] userBytes = user.getBytes(StandardCharsets.UTF_8);

View on GitHub (pinned to 6dac31d4c2)