{"record":{"id":"81c1fb64c6a043b3","repo":"prestodb/presto","slug":"keystore-certificate-is-expired-e-getmessage","errorCode":null,"errorMessage":"KeyStore certificate is expired: ${e.getMessage()}","messagePattern":"KeyStore certificate is expired: (.+?)","errorType":"exception","errorClass":"CertificateExpiredException","httpStatus":null,"severity":"critical","filePath":"presto-hive-metastore/src/main/java/com/facebook/presto/hive/metastore/thrift/HiveMetastoreClientFactory.java","lineNumber":220,"sourceCode":"     * @throws GeneralSecurityException\n     */\n    private static void validateKeyStoreCertificates(KeyStore keyStore)\n            throws GeneralSecurityException\n    {\n        for (String alias : list(keyStore.aliases())) {\n            if (!keyStore.isKeyEntry(alias)) {\n                continue;\n            }\n            final Certificate certificate = keyStore.getCertificate(alias);\n            if (!(certificate instanceof X509Certificate)) {\n                continue;\n            }\n\n            try {\n                ((X509Certificate) certificate).checkValidity();\n            }\n            catch (CertificateExpiredException e) {\n                throw new CertificateExpiredException(\"KeyStore certificate is expired: \" + e.getMessage());\n            }\n            catch (CertificateNotYetValidException e) {\n                throw new CertificateNotYetValidException(\"KeyStore certificate is not yet valid: \" + e.getMessage());\n            }\n        }\n    }\n}\n","sourceCodeStart":202,"sourceCodeEnd":228,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-hive-metastore/src/main/java/com/facebook/presto/hive/metastore/thrift/HiveMetastoreClientFactory.java#L202-L228","documentation":"Thrown by HiveMetastoreClientFactory.validateKeyStoreCertificates when an X509 certificate in the configured keystore fails checkValidity() because its notAfter date has passed. The factory validates every keystore certificate before building the SSL context for the Thrift metastore connection, so TLS cannot proceed with an expired credential.","triggerScenarios":"Calling HiveMetastoreClientFactory.create()/buildSslContext with hive.metastore.thrift.client.ssl.keystore-path pointing at a keystore containing a certificate whose validity period has ended.","commonSituations":"Keystore provisioned months ago and left untouched; CA-issued client cert with 1-year validity forgotten during renewal rotation; container images baked with certificates that expire while deployed; sandbox/CI environments with static test keystores.","solutions":["Obtain a renewed certificate from your CA and import it into the keystore with keytool -importcert (or replace the keypair), then point hive.metastore.thrift.client.ssl.keystore-path at the updated file","Check expiry with: keytool -list -v -keystore keystore.jks and look for 'Valid until'; automate alerting on the notAfter date","If only a trust-chain entry expired, update the truststore with the renewed CA certificate instead of replacing the client identity","As a last resort for internal testing only, regenerate a self-signed certificate with a longer validity and update both keystore and truststore on client and metastore"],"exampleFix":"// before\nthrow new CertificateExpiredException(\"KeyStore certificate is expired: \" + e.getMessage());\n// after\n# renew then reload\n# keytool -genkeypair -alias presto-metastore -keyalg RSA -validity 730 -keystore keystore.jks\n# config.properties: hive.metastore.thrift.client.ssl.keystore-path=/etc/presto/renewed-keystore.jks","handlingStrategy":"validation","validationCode":"import java.io.*;\nimport java.security.*;\nimport java.security.cert.*;\nimport java.util.*;\n\npublic static void validateKeystoreBeforeConnect(String path, char[] password) throws GeneralSecurityException, IOException {\n    KeyStore ks = KeyStore.getInstance(\"JKS\");\n    try (InputStream in = new FileInputStream(path)) {\n        ks.load(in, password);\n    }\n    Date now = new Date();\n    for (Enumeration<String> e = ks.aliases(); e.hasMoreElements(); ) {\n        Certificate c = ks.getCertificate(e.nextElement());\n        if (c instanceof X509Certificate) {\n            ((X509Certificate) c).checkValidity(now); // throws CertificateExpiredException early\n        }\n    }\n}","typeGuard":"public static boolean isExpired(X509Certificate cert) {\n    try { cert.checkValidity(); return false; }\n    catch (CertificateExpiredException e) { return true; }\n    catch (CertificateNotYetValidException e) { return false; }\n}","tryCatchPattern":"try {\n    createHiveMetastoreClient(config);\n} catch (CertificateExpiredException e) {\n    log.error(\"Keystore cert expired; renew before proceeding\", e);\n    throw new ConfigurationException(\"Renew the keystore certificate: \" + e.getMessage());\n}","preventionTips":["Alert on keystore certificate expiry dates well before notAfter (e.g. 30/14/7-day warnings via keytool -list -v parsing)","Automate certificate renewal and keystore redeployment (cert-manager, internal CA automation)","Use certificates with rolling renewal and verify them in CI before image builds","Keep the keystore path in config management with a checksum so renewals are tracked"],"tags":["ssl","keystore","certificate-expired","hive-metastore","tls"],"backgroundTag":"certificate-expired","analyzedSha":"55bb57d202de3b926896fa966c2c4a44c779634e","analyzedAt":"2026-09-04T12:50:26.162Z","contentChangedAt":"2026-09-04T12:50:26.162Z","schemaVersion":2},"datasetVersion":"2026-09-11T21:17:09.523Z"}