apache/cassandra · warning

Certificate from : with identity ' ' will expire in

Error message

Certificate from {}:{} with identity '{}' will expire in {}

What it means

This is a non-spammy warning (not an exception) logged by MutualTlsInternodeAuthenticator during mTLS internode authentication. The peer's client certificate is still valid (authentication succeeds, returns true), but it will expire soon — within the configured certificate_validity_warn_threshold. Cassandra emits it so operators rotate certificates before nodes start failing to connect.

Solutions

  1. Renew/reissue the client certificate on the remote node and restart or hot-reload its keystore/truststore (SSLFactory hot-reloading).
  2. Enable automated certificate rotation (e.g. cert-manager, vault) and distribute new keystores to all nodes.
  3. If the warning is too noisy for your ops practice, adjust certificate_validity_warn_threshold in cassandra.yaml to a smaller value.
  4. Watch internode_certificate_expiration_days metric (updated right after this log) to track worst-case expiry across the cluster.

Example fix

// before
certificate_validity_warn_threshold: 90d  // warns constantly as cert ages
// after
certificate_validity_warn_threshold: 14d  // plus automated rotation so certs are renewed before the threshold
Defensive patterns

Strategy: validation

Validate before calling

// Operator-side check before/alongside deployment
// Track Cassandra's own metric instead of calling the API:
// org.apache.cassandra.metrics: name=internode_certificate_expiration_days
// Alert when min value < warn threshold days.

Prevention

When it happens

Trigger: A peer node presents a client certificate whose remaining validity (minutesToCertificateExpiration from certificateValidityPeriodValidator.validate) is less than certificateValidityWarnThreshold while authenticating an internode connection.

Common situations: Long-running clusters with certificates generated once (e.g. by certmanager or manual openssl) that are approaching expiry without an automated rotation; threshold configured aggressively high (e.g. warn 90 days out); clocks skewed so remaining validity appears shorter than expected.

Understand the failure class

Related errors


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

Appendix: source

Thrown at src/java/org/apache/cassandra/auth/MutualTlsInternodeAuthenticator.java:203

            String identity = certificateValidator.identity(certificates);
            if (!certificateValidator.isValidCertificate(certificates))
            {
                noSpamLogger.error("Not a valid certificate from {}:{} with identity '{}'", remoteAddress, remotePort, identity);
                return false;
            }

            if (!trustedIdentities.contains(identity))
            {
                noSpamLogger.error("Unable to authenticate user {}", identity);
                return false;
            }

            int minutesToCertificateExpiration = certificateValidityPeriodValidator.validate(certificates);

            if (certificateValidityWarnThreshold != null
                && minutesToCertificateExpiration < certificateValidityWarnThreshold.toMinutes())
            {
                noSpamLogger.warn("Certificate from {}:{} with identity '{}' will expire in {}",
                                  remoteAddress, remotePort, identity,
                                  MutualTlsUtil.toHumanReadableCertificateExpiration(minutesToCertificateExpiration));
            }
            MutualTlsMetrics.instance.internodeCertificateExpirationDays.update(MutualTlsUtil.minutesToDays(minutesToCertificateExpiration));

            return true;
        }
        // Outbound connections don't need to be authenticated again in certificate based connections. SSL handshake
        // makes sure that we are talking to valid server by checking root certificates of the server in the
        // truststore of the client.
        return true;
    }

    @VisibleForTesting
    List<String> getIdentitiesFromKeyStore(final String outboundKeyStorePath,
                                           final String outboundKeyStorePassword,
                                           final String storeType)
    {

View on GitHub (pinned to 88fd0f6a0e)