prestodb/presto · error · CertificateExpiredException

KeyStore certificate is expired:

Error message

KeyStore certificate is expired: 

What it means

validateCertificates iterates every certificate in the keystore and calls checkValidity(); if a certificate's notAfter date has passed, it rethrows as CertificateExpiredException with the prefix 'KeyStore certificate is expired: '. This is a proactive check so TLS failures are reported clearly before any request is made instead of failing opaquely during the handshake.

Solutions

  1. Renew the expired certificate and import the new one into the keystore (keytool -importcert).
  2. Identify the expired entry with keytool -list -v and its expiration date.
  3. Set up expiration monitoring/renewal (e.g. certmgr or scheduled keytool checks).
  4. If it is a server CA chain update, import the renewed CA certificate into the trust store.

Example fix

// before
keytool -list -v -keystore truststore.jks  // entry expires 2025-01-01
// after
keytool -importcert -alias server-ca -file renewed-ca.crt -keystore truststore.jks
Defensive patterns

Strategy: validation

Validate before calling

Enumeration<String> aliases = keyStore.aliases();
while (aliases.hasMoreElements()) {
    java.security.cert.Certificate c = keyStore.getCertificate(aliases.nextElement());
    if (c instanceof X509Certificate) ((X509Certificate) c).checkValidity();  // throws CertificateExpiredException early
}

Try / catch

try { buildClient(...); } catch (ClientException e) { if (e.getCause() instanceof CertificateExpiredException) { /* renew cert, reload keystore */ } throw e; }

Prevention

When it happens

Trigger: setupSsl -> validateCertificates on a KeyStore containing an X509Certificate whose validity period has ended (current date > notAfter).

Common situations: Long-lived Presto CLI/JDBC client deployments where the server CA or client certificate expired; forgetting to rotate certificates; copying an old keystore into a new environment.

Understand the failure class

Related errors


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

Appendix: source

Thrown at presto-client/src/main/java/com/facebook/presto/client/OkHttpUtil.java:265

    }

    private static void validateCertificates(KeyStore keyStore)
            throws GeneralSecurityException
    {
        for (String alias : list(keyStore.aliases())) {
            if (!keyStore.isKeyEntry(alias)) {
                continue;
            }
            Certificate certificate = keyStore.getCertificate(alias);
            if (!(certificate instanceof X509Certificate)) {
                continue;
            }

            try {
                ((X509Certificate) certificate).checkValidity();
            }
            catch (CertificateExpiredException e) {
                throw new CertificateExpiredException("KeyStore certificate is expired: " + e.getMessage());
            }
            catch (CertificateNotYetValidException e) {
                throw new CertificateNotYetValidException("KeyStore certificate is not yet valid: " + e.getMessage());
            }
        }
    }

    private static KeyStore loadTrustStore(File trustStorePath, Optional<String> trustStorePassword, String trustStoreType)
            throws IOException, GeneralSecurityException
    {
        KeyStore trustStore = KeyStore.getInstance(trustStoreType);
        try {
            // attempt to read the trust store as a PEM file
            List<X509Certificate> certificateChain = PemReader.readCertificateChain(trustStorePath);
            if (!certificateChain.isEmpty()) {
                trustStore.load(null, null);
                for (X509Certificate certificate : certificateChain) {
                    X500Principal principal = certificate.getSubjectX500Principal();

View on GitHub (pinned to 55bb57d202)