{"record":{"id":"ab6f6c748d5ba4de","repo":"apereo/cas","slug":"expired-or-invalid-certificate-in-metadata-for","errorCode":null,"errorMessage":"Expired or invalid certificate in metadata for ","messagePattern":"Expired or invalid certificate in metadata for ","errorType":"exception","errorClass":"FilterException","httpStatus":null,"severity":"error","filePath":"support/cas-server-support-saml-idp-metadata/src/main/java/org/apereo/cas/support/saml/services/idp/metadata/filter/EntityDescriptorCertificatesExpirationFilter.java","lineNumber":43,"sourceCode":"\n    @Override\n    public XMLObject filter(@Nullable final XMLObject metadata,\n                            @NonNull final MetadataFilterContext context) throws FilterException {\n\n        if (metadata instanceof final EntityDescriptor ed) {\n            for (val role : ed.getRoleDescriptors()) {\n                for (val kd : role.getKeyDescriptors()) {\n                    val ki = kd.getKeyInfo();\n                    for (val x509 : ki.getX509Datas()) {\n                        for (val xmlCert : x509.getX509Certificates()) {\n                            try {\n                                val cert = X509Support.decodeCertificate(xmlCert.getValue());\n                                LOGGER.debug(\"Evaluating certificate [{}] in metadata for [{}]. Not Before [{}], Not After [{}]\",\n                                    cert.getSubjectX500Principal().getName(), ed.getEntityID(), cert.getNotBefore(), cert.getNotAfter());\n                                cert.checkValidity();\n                            } catch (final CertificateException e) {\n                                LoggingUtils.error(LOGGER, e);\n                                throw new FilterException(\"Expired or invalid certificate in metadata for \" + ed.getEntityID());\n                            }\n                        }\n                    }\n                }\n            }\n        }\n        return metadata;\n    }\n}\n\n","sourceCodeStart":25,"sourceCodeEnd":54,"githubUrl":"https://github.com/apereo/cas/blob/e7288fc434b4f4505b8452e1a57e8fb3111bb863/support/cas-server-support-saml-idp-metadata/src/main/java/org/apereo/cas/support/saml/services/idp/metadata/filter/EntityDescriptorCertificatesExpirationFilter.java#L25-L54","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["Obtain updated metadata from the IdP containing valid certificates and refresh the cached copy.","Set the system clock/timezone correctly on the CAS server.","Temporarily remove the expiration filter from the filter chain if policy permits (and rotate certs promptly).","Contact the IdP administrator to publish corrected metadata."],"exampleFix":"// before\n<!-- metadata contains expired cert from 2023 -->\n// after\n<!-- refresh metadata so NotAfter is in the future, or re-import updated IdP metadata -->","handlingStrategy":"try-catch","validationCode":"val cert = X509Support.decodeCertificate(certXml.getValue());\ncert.checkValidity(); // throws CertificateException if expired or not-yet-valid","typeGuard":"boolean certIsValid(X509Certificate c) { try { c.checkValidity(); return true; } catch (CertificateException e) { return false; } }","tryCatchPattern":"try {\n    filterChain.process(entityDescriptor, context);\n} catch (FilterException e) {\n    LOGGER.warn(\"Metadata rejected: {}\", e.getMessage());\n    metrics.increment(\"saml.metadata.certExpired\");\n}","preventionTips":["Monitor certificate NotAfter dates in trusted IdP metadata and alert before expiry.","Refresh metadata on a schedule from the IdP's published source.","Keep CAS server clocks NTP-synced.","Test certificate rotation procedures with IdP partners."],"tags":["saml","metadata","certificate","x509","expired-certificate"],"backgroundTag":"certificate-expired","analyzedSha":"e7288fc434b4f4505b8452e1a57e8fb3111bb863","analyzedAt":"2026-09-08T15:39:16.015Z","contentChangedAt":"2026-09-08T15:39:16.015Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}