{"record":{"id":"70f0dbed9be1dd6a","repo":"apereo/cas","slug":"all-crls-retrieved-have-expired-applying-crl-expi","errorCode":null,"errorMessage":"All CRLs retrieved have expired. Applying CRL expiration policy...","messagePattern":"All CRLs retrieved have expired\\. Applying CRL expiration policy\\.\\.\\.","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"support/cas-server-support-x509-core/src/main/java/org/apereo/cas/adaptors/x509/authentication/revocation/checker/AbstractCRLRevocationChecker.java","lineNumber":77,"sourceCode":"    @Override\n    public void check(@NonNull final X509Certificate cert) throws GeneralSecurityException {\n        LOGGER.debug(\"Evaluating certificate revocation status for [{}]\", CertUtils.toString(cert));\n        val crls = getCRLs(cert);\n\n        if (crls == null || crls.isEmpty()) {\n            LOGGER.warn(\"CRL data is not available for [{}]\", CertUtils.toString(cert));\n            this.unavailableCRLPolicy.apply(null);\n            return;\n        }\n\n        val expiredCrls = new ArrayList<X509CRL>(crls.size());\n        crls.stream().filter(CertUtils::isExpired).forEach(crl -> {\n            LOGGER.warn(\"CRL data expired on [{}]\", crl.getNextUpdate());\n            expiredCrls.add(crl);\n        });\n\n        if (crls.size() == expiredCrls.size()) {\n            LOGGER.warn(\"All CRLs retrieved have expired. Applying CRL expiration policy...\");\n            for (val crl : expiredCrls) {\n                this.expiredCRLPolicy.apply(crl);\n            }\n        } else {\n            crls.removeAll(expiredCrls);\n            LOGGER.debug(\"Valid CRLs [{}] found that are not expired yet\", crls);\n\n            val revokedCrls = crls.stream().map(crl -> crl.getRevokedCertificate(cert)).filter(Objects::nonNull).toList();\n            if (revokedCrls.size() == crls.size()) {\n                val entry = revokedCrls.getFirst();\n                LOGGER.warn(\"All CRL entries have been revoked. Rejecting the first entry [{}]\", entry);\n                throw new RevokedCertificateException(entry);\n            }\n        }\n    }\n\n    /**\n     * Records the addition of a new CRL entry.","sourceCodeStart":59,"sourceCodeEnd":95,"githubUrl":"https://github.com/apereo/cas/blob/e7288fc434b4f4505b8452e1a57e8fb3111bb863/support/cas-server-support-x509-core/src/main/java/org/apereo/cas/adaptors/x509/authentication/revocation/checker/AbstractCRLRevocationChecker.java#L59-L95","documentation":"Logged when every CRL retrieved for the certificate has expired (expiredCrls.size() == crls.size()). CAS then applies the configured expiredCRLPolicy (e.g. ALLOW, DENY, or throw), so this message usually precedes either an authentication denial or a policy-driven exception.","triggerScenarios":"AbstractCRLRevocationChecker.check() runs and CertUtils.isExpired(crl) is true for all fetched CRLs — none are within their nextUpdate window.","commonSituations":"CA stopped publishing CRL updates (CA shutdown, subscription lapsed); long-outdated cached CRL resource configured in CAS; server clock far in the future due to misconfigured NTP.","solutions":["Obtain a current CRL from the CA and replace the expired one.","Fix server clock/NTP if skew caused all CRLs to appear expired.","Set the expired-CRL policy to ALLOW only if the security posture accepts validating against expired revocation data; otherwise keep DENY and treat this as a CA operational incident.","Switch to OCSP revocation checking if CRL freshness cannot be guaranteed."],"exampleFix":"// before\ncas.authn.x509.crl.expired-crl-policy=ALLOW\n// after\ncas.authn.x509.crl.expired-crl-policy=DENY\n# plus scheduled CRL refresh to keep data current","handlingStrategy":"fallback","validationCode":"boolean allExpired = crls.stream().allMatch(c -> c.getNextUpdate() == null\n        || c.getNextUpdate().toInstant().isBefore(Instant.now()));\nif (allExpired) { /* refresh CRLs or fail fast before check() */ }","typeGuard":null,"tryCatchPattern":"try {\n    checker.check(cert);\n} catch (GeneralSecurityException e) {\n    // expiredCRLPolicy=DENY path: surface as auth failure with reason\n    throw new GeneralSecurityException(\"All CRLs expired for cert\", e);\n}","preventionTips":["Automate CRL renewal so all CRLs never lapse simultaneously.","Verify CA operational health — all-expired usually means the CA stopped publishing.","Fix NTP/time sync before blaming CRL freshness.","Choose expired-CRL policy deliberately and document the security tradeoff."],"tags":["x509","crl","expired","revocation-policy"],"backgroundTag":"crl-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"}