prestodb/presto · error · GeneralSecurityException

Failed to load truststore as both PEM and KeyStore format…

Error message

Failed to load truststore as both PEM and KeyStore format. PEM error: %s, KeyStore error: %s

What it means

loadTrustStore first tries to parse the configured file as PEM; if that fails it falls back to loading it as a JKS/KeyStore. When both attempts fail it throws GeneralSecurityException with a combined message containing the PEM error and the KeyStore error, meaning the file is neither valid PEM nor a valid KeyStore (or the password is wrong).

Solutions

  1. Read the 'PEM error' and 'KeyStore error' portions of the message to see why each parse failed
  2. Verify the file type: openssl crl2pkcs7 -nocrl -certfile f | openssl pkcs7 -print_certs (PEM) or keytool -list (JKS/PKCS12)
  3. Fix the configured path to point at a real truststore containing CA certificates
  4. If it is a KeyStore, confirm the configured trustStorePassword matches

Example fix

// before (catalog.properties)
http-server.https.truststore.path=/etc/pki/server-keystore.jks   # wrong file
// after
http-server.https.truststore.path=/etc/pki/ca-truststore.jks
http-server.https.truststore.key=changeit
Defensive patterns

Strategy: validation

Validate before calling

# verify the file is either valid PEM or a valid KeyStore before configuring it
openssl crl2pkcs7 -nocrl -certfile $TS_FILE | openssl pkcs7 -print_certs >/dev/null 2>&1 \
  || keytool -list -keystore $TS_FILE -storepass $TS_PASS >/dev/null 2>&1 \
  || echo NOT-A-TRUSTSTORE

Prevention

When it happens

Trigger: loadTrustStore (called from createSSLContext) is given a path whose content parses as neither PEM certificates nor a KeyStore — wrong file entirely, corrupted download, or wrong trustStorePassword making the KeyStore load throw IOException.

Common situations: Pointing truststore.path at the keystore file (or vice versa); password mismatch on a JKS store; secret mounted as a truncated/empty file; PKCS12 file supplied while expecting JKS handling quirks.

Related errors


AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04). Data as JSON: /api/errors/0eb25f5153ef9b18. Report an issue: GitHub.

Appendix: source

Thrown at presto-plugin-toolkit/src/main/java/com/facebook/presto/plugin/base/security/SslContextProvider.java:242

            }
        }
        catch (IOException | GeneralSecurityException e) {
            log.debug("Failed to load truststore as PEM format: {}", e.getMessage());
            lastException = e;
        }

        // If PEM loading failed, try standard KeyStore format
        if (!loaded) {
            try {
                log.debug("Attempting to load truststore as JKS format");
                try (InputStream inputStream = Files.newInputStream(trustStorePath.toPath())) {
                    trustStore.load(inputStream, trustStorePassword.map(String::toCharArray).orElse(null));
                }
                log.debug("Successfully loaded truststore as JKS format");
            }
            catch (IOException | GeneralSecurityException e) {
                log.debug("Failed to load truststore as JKS format: {}", e.getMessage());
                throw new GeneralSecurityException(
                        "Failed to load truststore as both PEM and KeyStore format. " +
                                "PEM error: " + (lastException != null ? lastException.getMessage() : "unknown") +
                                ", KeyStore error: " + e.getMessage(), e);
            }
        }

        // Verify the truststore is not empty
        try {
            List<String> aliases = Collections.list(trustStore.aliases());
            if (aliases.isEmpty()) {
                throw new GeneralSecurityException("Loaded truststore is empty - no certificates found in: " + trustStorePath);
            }
            log.debug("Truststore loaded with {} certificate(s)", aliases.size());
        }
        catch (KeyStoreException e) {
            throw new GeneralSecurityException("Failed to verify truststore contents", e);
        }

View on GitHub (pinned to 55bb57d202)