prestodb/presto · critical · RuntimeException
Unexpected default trust managers:
Error message
Unexpected default trust managers:
What it means
buildSslContext initializes a TrustManagerFactory from the configured truststore and expects the default algorithm to produce exactly one trust manager that is an X509TrustManager. If the array is empty, has multiple entries, or is of a different class, the code cannot build the TLS context for the Elasticsearch client and throws RuntimeException. This indicates the truststore is empty, corrupt, or contains entries the default algorithm cannot consolidate.
Source
Thrown at presto-elasticsearch/src/main/java/com/facebook/presto/elasticsearch/client/ElasticsearchClient.java:336
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(keyStore, keyManagerPassword);
keyManagers = keyManagerFactory.getKeyManagers();
}
// load TrustStore if configured, otherwise use KeyStore
KeyStore trustStore = keyStore;
if (trustStorePath.isPresent()) {
trustStore = loadTrustStore(trustStorePath.get(), trustStorePassword);
}
// create TrustManagerFactory
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(trustStore);
// get X509TrustManager
TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
if ((trustManagers.length != 1) || !(trustManagers[0] instanceof X509TrustManager)) {
throw new RuntimeException("Unexpected default trust managers:" + Arrays.toString(trustManagers));
}
X509TrustManager trustManager = (X509TrustManager) trustManagers[0];
// create SSLContext
SSLContext result = SSLContext.getInstance("TLS");
result.init(keyManagers, new TrustManager[] {trustManager}, null);
return Optional.of(result);
}
catch (GeneralSecurityException | IOException e) {
throw new PrestoException(ELASTICSEARCH_SSL_INITIALIZATION_FAILURE, e);
}
}
private static KeyStore loadTrustStore(File trustStorePath, Optional<String> trustStorePassword)
throws IOException, GeneralSecurityException
{
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
try {View on GitHub (pinned to 55bb57d202)
Solutions
- Verify the truststore file exists, is a valid JKS/PKCS12 keystore, and actually contains the CA certificate (keytool -list -v -keystore truststore.jks).
- Check elasticsearch.security.truststore-password is correct; an empty keystore yields no usable trust managers.
- Re-create the truststore by importing the server CA: keytool -importcert -alias es-ca -file ca.crt -keystore truststore.jks.
- Upgrade the connector / JDK so the default algorithm returns an X509TrustManager.
Example fix
// before (empty/garbage file mounted) elasticsearch.security.truststore=/secrets/tls (empty file) // after keytool -importcert -alias es-ca -file ca.pem -keystore /secrets/truststore.jks -storepass changeit elasticsearch.security.truststore=/secrets/truststore.jks
Defensive patterns
Strategy: validation
Validate before calling
// verify the truststore before configuring Presto keytool -list -v -keystore /etc/presto/es-truststore.jks -storepass $PASS # expect at least one trustedCertEntry; exit code 0 and non-empty output
Try / catch
// wrap connector bootstrap
try {
connector = esConnectorFactory.create(...);
} catch (RuntimeException e) {
if (e.getMessage() != null && e.getMessage().startsWith("Unexpected default trust managers:")) {
throw new ConfigurationException("truststore empty/corrupt: " + e.getMessage());
}
throw e;
} Prevention
- Always keytool -list the truststore after creating/mounting it.
- Use JKS or PKCS12 explicitly and match the file format.
- Mount Kubernetes secrets with correct file contents, not emptyDirs.
- Keep truststore password in a secret manager, verify with a startup check.
When it happens
Trigger: Configuring elasticsearch.security.truststore (or keystore path) pointing to a keystore that is empty, wrong format, unreadable, or whose default TrustManagerFactory result is not a single X509TrustManager.
Common situations: Wrong truststore path or password; truststore created with an unusual type (e.g. PKCS12 vs JKS mismatch); file mounted empty in Kubernetes secret; Java security providers overridden.
Related errors
- Error setting up SSL:
- KeyStore certificate is expired:
- Expected exactly one X509TrustManager, but found: ${trustMan
- GENERIC_INTERNAL_ERROR
- Truststore is empty - no trusted certificates found
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/c444f81ee1960cdd.
Report an issue: GitHub.