apereo/cas · error · FilterException

Expired or invalid certificate in metadata for

Error message

Expired or invalid certificate in metadata for 

What it means

Part of the metadata certificate expiration filter: for every X509 certificate found in an IdP entity descriptor, cert.checkValidity() is called. If the certificate is expired (NotAfter passed) or not yet valid (NotBefore in future) or otherwise unparsable, a FilterException is raised so bad metadata cannot be trusted.

Solutions

  1. Obtain updated metadata from the IdP containing valid certificates and refresh the cached copy.
  2. Set the system clock/timezone correctly on the CAS server.
  3. Temporarily remove the expiration filter from the filter chain if policy permits (and rotate certs promptly).
  4. Contact the IdP administrator to publish corrected metadata.

Example fix

// before
<!-- metadata contains expired cert from 2023 -->
// after
<!-- refresh metadata so NotAfter is in the future, or re-import updated IdP metadata -->
Defensive patterns

Strategy: try-catch

Validate before calling

val cert = X509Support.decodeCertificate(certXml.getValue());
cert.checkValidity(); // throws CertificateException if expired or not-yet-valid

Type guard

boolean certIsValid(X509Certificate c) { try { c.checkValidity(); return true; } catch (CertificateException e) { return false; } }

Try / catch

try {
    filterChain.process(entityDescriptor, context);
} catch (FilterException e) {
    LOGGER.warn("Metadata rejected: {}", e.getMessage());
    metrics.increment("saml.metadata.certExpired");
}

Prevention

When it happens

Trigger: Running the metadata filters pipeline over metadata containing an X509Certificate whose validity window does not include the current time, or a value that cannot be decoded into a certificate (decodeCertificate succeeds but checkValidity, or decoding itself, throws CertificateException).

Common situations: IdP rotated its signing certificate and old expired cert still present in metadata; CAS clock skew or wrong system time; stale cached metadata file; self-signed test cert past expiry.

Understand the failure class

Related errors


AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08). Data as JSON: /api/errors/ab6f6c748d5ba4de. Report an issue: GitHub.

Appendix: source

Thrown at support/cas-server-support-saml-idp-metadata/src/main/java/org/apereo/cas/support/saml/services/idp/metadata/filter/EntityDescriptorCertificatesExpirationFilter.java:43

    @Override
    public XMLObject filter(@Nullable final XMLObject metadata,
                            @NonNull final MetadataFilterContext context) throws FilterException {

        if (metadata instanceof final EntityDescriptor ed) {
            for (val role : ed.getRoleDescriptors()) {
                for (val kd : role.getKeyDescriptors()) {
                    val ki = kd.getKeyInfo();
                    for (val x509 : ki.getX509Datas()) {
                        for (val xmlCert : x509.getX509Certificates()) {
                            try {
                                val cert = X509Support.decodeCertificate(xmlCert.getValue());
                                LOGGER.debug("Evaluating certificate [{}] in metadata for [{}]. Not Before [{}], Not After [{}]",
                                    cert.getSubjectX500Principal().getName(), ed.getEntityID(), cert.getNotBefore(), cert.getNotAfter());
                                cert.checkValidity();
                            } catch (final CertificateException e) {
                                LoggingUtils.error(LOGGER, e);
                                throw new FilterException("Expired or invalid certificate in metadata for " + ed.getEntityID());
                            }
                        }
                    }
                }
            }
        }
        return metadata;
    }
}

View on GitHub (pinned to e7288fc434)