apache/cassandra · warning

Certificate for expired on

Error message

Certificate for {} expired on {}

What it means

During SSL context construction, checkExpiredCerts iterates key store aliases and warns when an X.509 certificate's notAfter date is in the past. It sets hasExpiredCerts, which (with strict expiration checking enabled) causes SSLFactory to throw SSLException. The keystore still works for non-strict setups, but expired certs cause TLS handshake failures with peers.

Solutions

  1. Renew the certificate and replace it in the keystore referenced by server/client_encryption_options.
  2. Verify expiry with: keytool -list -v -keystore <ks> | grep -A1 until.
  3. Automate renewal (cert-manager/lets-encrypt) and monitor expiry dates.
  4. As a temporary measure, strict_mode can be tuned, but renewal is the only real fix.

Example fix

// before
openssl x509 -in old.crt -checkend 0  # expired
// after: renew and rebuild keystore
keytool -importcert -alias node1 -file renewed.crt -keystore .keystore
Defensive patterns

Strategy: validation

Validate before calling

// check cert expiry before building SSL context
CertificateFactory cf = CertificateFactory.getInstance("X.509");
X509Certificate cert = (X509Certificate) cf.generateCertificate(new FileInputStream("node.crt"));
if (cert.getNotAfter().before(new Date())) throw new IllegalStateException("Renew cert: expired " + cert.getNotAfter());

Try / catch

try {
    sslContext = sslFactory.createSSLContext();
} catch (SSLException | CertificateExpiredException e) {
    throw new IllegalStateException("TLS certs expired - rotate keystore", e);
}

Prevention

When it happens

Trigger: getKeyManagerFactory() loads a keystore whose certificate for some alias has expires.before(now); logged per expired alias.

Common situations: Forgotten certificate renewal in long-lived clusters; TLS errors like 'certificate_expired' after a cert passes its notAfter date; CI nodes with stale test certs.

Understand the failure class

Related errors


AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10). Data as JSON: /api/errors/aebff109340676c4. Report an issue: GitHub.

Appendix: source

Thrown at src/java/org/apache/cassandra/security/FileBasedSslContextFactory.java:243

        {
            throw new SSLException("failed to build key manager store for secure connections", e);
        }
    }

    protected boolean checkExpiredCerts(KeyStore ks) throws KeyStoreException
    {
        boolean hasExpiredCerts = false;
        final Date now = new Date(Clock.Global.currentTimeMillis());
        for (Enumeration<String> aliases = ks.aliases(); aliases.hasMoreElements(); )
        {
            String alias = aliases.nextElement();
            if (ks.getCertificate(alias).getType().equals("X.509"))
            {
                Date expires = ((X509Certificate) ks.getCertificate(alias)).getNotAfter();
                if (expires.before(now))
                {
                    hasExpiredCerts = true;
                    logger.warn("Certificate for {} expired on {}", alias, expires);
                }
            }
        }
        return hasExpiredCerts;
    }

    /**
     * Helper class for hot reloading SSL Contexts
     */
    protected static class HotReloadableFile
    {
        private final File file;
        private volatile long lastModTime;

        HotReloadableFile(String path)
        {
            file = new File(path);
            lastModTime = file.lastModified();

View on GitHub (pinned to 88fd0f6a0e)