testcontainers/testcontainers-java · error · IOException
Unable to create custom SSL factory instance
Error message
Unable to create custom SSL factory instance
What it means
When HttpWaitStrategy is configured with .usingTls().allowInsecure(), openConnection builds an SSLContext with a trust-all TrustManager and installs its socket factory on the connection. If SSLContext.getInstance("SSL") or sc.init(...) throws (NoSuchAlgorithmException / KeyManagementException), the strategy wraps it in this IOException. It is an environment/JRE problem, not an app problem.
Solutions
- Check available algorithms: Security.getAlgorithms("SSLContext") — use .usingTls() only if SSL/TLS is present
- Run on a standard, full JDK/JRE (e.g. official Temurin images)
- Upgrade the JVM/Testcontainers version; newer code may request "TLS" instead of "SSL"
- If TLS is not actually needed, drop .usingTls() and wait over plain HTTP
Example fix
// before new HttpWaitStrategy().usingTls().allowInsecure().forPort(8443); // after // only if the endpoint really is HTTPS; otherwise wait over HTTP new HttpWaitStrategy().forPort(8080);
Defensive patterns
Strategy: try-catch
Validate before calling
// Ensure the JVM can create the SSL context before configuring TLS waits
if (!java.security.Security.getAlgorithms("SSLContext").stream()
.anyMatch(a -> a.equalsIgnoreCase("SSL") || a.equalsIgnoreCase("TLS"))) {
throw new IllegalStateException("No SSLContext provider available; avoid .usingTls()");
} Try / catch
try {
container.waitingFor(new HttpWaitStrategy().usingTls().allowInsecure()).start();
} catch (ContainerLaunchException e) {
Throwable root = e;
while (root.getCause() != null) root = root.getCause();
if (root instanceof NoSuchAlgorithmException || root instanceof KeyManagementException) {
// fall back to plain HTTP wait or fix the JRE
}
throw e;
} Prevention
- Use full standard JDK/JRE images in test environments
- Only enable .usingTls() when the endpoint truly serves HTTPS
- Keep Testcontainers updated for SSL-handling fixes
When it happens
Trigger: Calling .usingTls(true).allowInsecure(true) on a JRE lacking the requested SSL algorithm or failing key-manager initialization (restricted crypto policy, broken security provider, unusual JRE build).
Common situations: Running on minimal/custom JRE builds (jlink images) missing crypto providers; ancient or exotic JVMs without 'SSL' algorithm; corporate JVM with stripped security providers.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- Exception while creating SSLSocketFactory
- HTTP response code was
- Response: did not match predicate
- Timed out waiting for URL to be accessible
- Timed out waiting for log output matching
AI-assisted analysis of testcontainers/testcontainers-java@8e549514e3 (2026-09-12).
Data as JSON: /api/errors/bd9eb67e14593315.
Report an issue: GitHub.
Appendix: source
Thrown at core/src/main/java/org/testcontainers/containers/wait/strategy/HttpWaitStrategy.java:369
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType, Socket socket) {}
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType, SSLEngine engine) {}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType, SSLEngine engine) {}
},
};
try {
// Create custom SSL context and set the "trust all certificates" trust manager
final SSLContext sc = SSLContext.getInstance("SSL");
sc.init(new KeyManager[0], trustAllCerts, new SecureRandom());
connection.setSSLSocketFactory(sc.getSocketFactory());
} catch (final NoSuchAlgorithmException | KeyManagementException ex) {
throw new IOException("Unable to create custom SSL factory instance", ex);
}
}
return connection;
} else {
return (HttpURLConnection) new URL(uri).openConnection();
}
}
/**
* Build the URI on which to check if the container is ready.
*
* @param livenessCheckPort the liveness port
* @return the liveness URI
*/
private URI buildLivenessUri(int livenessCheckPort) {
final String scheme = (tlsEnabled ? "https" : "http") + "://";
final String host = waitStrategyTarget.getHost();View on GitHub (pinned to 8e549514e3)