quarkusio/quarkus · error · RuntimeException

Failed to load truststore

Error message

Failed to load truststore

What it means

Thrown during HttpClientBuilder.build() when KeystoreUtil.loadKeyStore cannot load the configured truststore file (wrong path, wrong password, unreadable file, or invalid format). The original exception is wrapped in a RuntimeException so client construction fails fast.

Source

Thrown at extensions/keycloak-authorization/runtime/src/main/java/io/quarkus/keycloak/pep/runtime/HttpClientBuilder.java:427

            }
            return clientBuilder.build();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public HttpClient build(AdapterHttpClientConfig adapterConfig) {
        disableCookieCache(true); // disable cookie cache as we don't want sticky sessions for load balancing

        String truststorePath = adapterConfig.getTruststore();
        if (truststorePath != null) {
            truststorePath = EnvUtil.replace(truststorePath);
            String truststorePassword = adapterConfig.getTruststorePassword();
            try {
                this.truststore = KeystoreUtil.loadKeyStore(truststorePath, truststorePassword);
            } catch (Exception e) {
                throw new RuntimeException("Failed to load truststore", e);
            }
        }
        String clientKeystore = adapterConfig.getClientKeystore();
        if (clientKeystore != null) {
            clientKeystore = EnvUtil.replace(clientKeystore);
            String clientKeystorePassword = adapterConfig.getClientKeystorePassword();
            try {
                KeyStore clientCertKeystore = KeystoreUtil.loadKeyStore(clientKeystore, clientKeystorePassword);
                keyStore(clientCertKeystore, clientKeystorePassword);
            } catch (Exception e) {
                throw new RuntimeException("Failed to load keystore", e);
            }
        }

        HttpClientBuilder.HostnameVerificationPolicy policy = HttpClientBuilder.HostnameVerificationPolicy.WILDCARD;
        if (adapterConfig.isAllowAnyHostname())
            policy = HttpClientBuilder.HostnameVerificationPolicy.ANY;
        connectionPoolSize(adapterConfig.getConnectionPoolSize());

View on GitHub (pinned to e1c734241f)

Solutions

  1. Verify the truststore file exists at the configured path inside the runtime environment (ls the exact resolved path, including env-substituted values).
  2. Confirm the truststore password matches the keystore's password.
  3. Check the keystore format: create it with keytool -importcert -file ca.crt -keystore truststore.jks (or .p12 with -storetype PKCS12) and match the configured type.
  4. Ensure the file is readable by the process user and is included in the container image/volume mount.

Example fix

// before
keytool -importcert -file ca.pem -keystore truststore
# password mismatch, path wrong -> Failed to load truststore
// after
keytool -importcert -alias keycloak-ca -file ca.pem -keystore truststore.jks -storepass changeit -noprompt
quarkus.oidc.tls.trust-store-file=/opt/certs/truststore.jks
quarkus.oidc.tls.trust-store-password=changeit
Defensive patterns

Strategy: validation

Validate before calling

File ts = new File(resolvedTruststorePath);
if (!ts.isFile() || !ts.canRead())
    throw new IllegalStateException("Truststore missing/unreadable: " + ts.getAbsolutePath());
// password check: try loading before startup
KeyStore ks = KeyStore.getInstance("JKS");
try (InputStream in = new FileInputStream(ts)) { ks.load(in, truststorePassword.toCharArray()); }

Try / catch

try {
    HttpClientBuilder hb = HttpClientBuilder.create(adapterConfig);
    client = hb.build();
} catch (RuntimeException e) {
    if (e.getMessage() != null && e.getMessage().contains("Failed to load truststore")) {
        log.error("Check truststore path/password/format: {}", adapterConfig.getTruststore(), e.getCause());
    }
    throw e;
}

Prevention

When it happens

Trigger: AdapterConfig has a truststore path set (e.g. quarkus.oidc.tls.trust-store-file / adapter truststore config) but the file does not exist at runtime, the truststore password is wrong, or the file is not a loadable keystore (JKS/PKCS12 mismatch or corrupt).

Common situations: Container image missing the mounted truststore file; path uses a container-invisible location; password changed on the keystore; certificate exported in PEM instead of a keystore format; env-var substitution (EnvUtil.replace) yields an unexpected path.

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/b0604f76a36ddfbf. Report an issue: GitHub.