karatelabs/karate · critical · IllegalStateException

could not build the pooled client's SSL context

Error message

could not build the pooled client's SSL context

What it means

PooledHttpClientFactory builds a trust-all TLS strategy for its pooled Apache HTTP client by constructing an SSLContext. If SSL context initialization fails (keystore problems, unavailable TLS algorithm, security provider issues), it wraps the cause in an IllegalStateException with this message.

Solutions

  1. Inspect the wrapped cause (e.getCause()) to find the actual SSL failure
  2. Remove or fix custom -Djavax.net.ssl.trustStore/keyStore system properties pointing at missing or corrupt files
  3. Run on a supported JDK with standard TLS providers (check `java -version` and try a recent LTS)
  4. If a custom keystore is intentional, verify its password and format (PKCS12 vs JKS)

Example fix

// before (startup flags)
java -Djavax.net.ssl.trustStore=/missing/cacerts -jar sim.jar
// after
java -jar sim.jar   # or point trustStore at a valid keystore file
Defensive patterns

Strategy: try-catch

Try / catch

try { return PooledHttpClientFactory.withTrustAllTls(); } catch (IllegalStateException e) { throw new RuntimeException("SSL context init failed: " + e.getCause(), e); }

Prevention

When it happens

Trigger: Creating the pooled client factory on a JVM where the default SSLContext cannot be built — e.g. TLS.getSystemTrustStore misconfigured, a broken javax.net.ssl custom keystore, or a restricted JCE environment lacking required algorithms.

Common situations: Custom truststore paths via -Djavax.net.ssl.* pointing at missing/corrupt files; FIPS-enabled JVMs where default algorithms are unavailable; exotic JDKs or old Java versions lacking TLS 1.3; malformed keystore passwords in the environment.

Understand the failure class

Related errors


AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12). Data as JSON: /api/errors/8e97063c650565eb. Report an issue: GitHub.

Appendix: source

Thrown at karate-gatling/src/main/java/io/karatelabs/gatling/PooledHttpClientFactory.java:163

    private static TlsSocketStrategy trustAllTlsStrategy() {
        try {
            SSLContext context = SSLContextBuilder.create()
                    .loadTrustMaterial(null, (chain, authType) -> true)
                    .build();
            // TlsSocketStrategy rather than the SSLConnectionSocketFactory karate-core still uses:
            // that one is deprecated in httpclient5 5.6 and this is new code, so it takes the
            // replacement instead of a @SuppressWarnings.
            //
            // The policy has to be CLIENT and cannot be left to default. Since 5.4 the default is
            // BUILTIN, which asks the JDK to verify the hostname during the handshake — before the
            // supplied verifier is consulted at all, so a NoopHostnameVerifier is simply never
            // reached. Measured: against a certificate with no subject alternative names, the
            // default failed every request with "No subject alternative names present" while the
            // trust-all context was working exactly as intended.
            return new DefaultClientTlsStrategy(context, HostnameVerificationPolicy.CLIENT,
                    NoopHostnameVerifier.INSTANCE);
        } catch (Exception e) {
            throw new IllegalStateException("could not build the pooled client's SSL context", e);
        }
    }

    @Override
    public HttpClient create() {
        return new PooledApacheHttpClient();
    }

    /**
     * Closes the scenario's wrapper, which returns its connections to the pool rather than
     * shutting it: {@code ApacheHttpClient} builds with {@code setConnectionManagerShared(true)}
     * whenever {@code sharedConnectionManager()} is non-null.
     */
    @Override
    public void release(HttpClient client) {
        try {
            client.close();
        } catch (Exception e) {

View on GitHub (pinned to a22eb90246)