{"record":{"id":"32c01ccbebb956a8","repo":"apereo/cas","slug":"crl-data-is-not-available-for","errorCode":null,"errorMessage":"CRL data is not available for [{}]","messagePattern":"CRL data is not available for \\[(.+?)\\]","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":65,"sourceCode":"     *                             that produces the cert.\n     * @param unavailableCRLPolicy the unavailable crl policy\n     * @param expiredCRLPolicy     the expired crl policy\n     */\n    protected AbstractCRLRevocationChecker(final boolean checkAll,\n                                        final RevocationPolicy<Void> unavailableCRLPolicy,\n                                        final RevocationPolicy<X509CRL> expiredCRLPolicy) {\n        this.checkAll = checkAll;\n        this.unavailableCRLPolicy = Objects.requireNonNullElseGet(unavailableCRLPolicy, DenyRevocationPolicy::new);\n        this.expiredCRLPolicy = Objects.requireNonNullElseGet(expiredCRLPolicy, () -> new ThresholdExpiredCRLRevocationPolicy(0));\n    }\n\n    @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);","sourceCodeStart":47,"sourceCodeEnd":83,"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#L47-L83","documentation":"Logged in AbstractCRLRevocationChecker.check() when getCRLs(cert) returns null or an empty collection, meaning no CRL could be fetched or computed for the certificate. The checker then delegates to the configured unavailableCRLPolicy (e.g. ALLOW or DENY), so the outcome depends on CAS x509 configuration. It is a warning because it may simply reflect an unreachable CRL distribution point rather than a code bug.","triggerScenarios":"X509 credential revocation checking is enabled and the certificate's CRL distribution point URL is unreachable, the CRL fetch returns nothing, or no revocation checker is configured to supply CRL data for the certificate.","commonSituations":"CRL distribution point host unreachable/offline from the CAS server (firewall, DNS, expired URL); certificate issued without CRLDP extension; x509 revocation checking turned on but no CRL resource configured; caching fetcher returning expired/empty entries.","solutions":["Verify the CRL distribution point URL is reachable from the CAS server: 'curl -v <crlDP-url>'.","Set cas.authn.x509.crl.* / unavailable-CRL-policy explicitly (allow or deny) so behavior is intentional.","Configure a fetcher/cache (e.g. ResourceCRLFetcher, CRL distribution point caching) or point CAS at an OCSP responder instead.","If the certificate legitimately has no CRLDP, switch to OCSP-based checking or disable revocation for that CA."],"exampleFix":"// before (cas.properties)\ncas.authn.x509.crl.revocation-policy=ALLOW\n// after\ncas.authn.x509.crl.revocation-policy=DENY\ncas.authn.x509.crl.fetcher=resource\ncas.authn.x509.crl.resource.location=file:/etc/cas/crls/ca.crl","handlingStrategy":"validation","validationCode":"String crlDp = \"\"; // extract from cert CRL distribution points extension\nif (crlDp == null || crlDp.isBlank()) {\n    throw new IllegalStateException(\"Certificate has no CRL distribution point; enable OCSP or skip revocation\");\n}","typeGuard":"if (crls == null || crls.isEmpty()) { /* handle unavailable-CRL case explicitly before check() */ }","tryCatchPattern":"try {\n    checker.check(cert);\n} catch (RevokedCertificateException e) {\n    throw e;\n} catch (GeneralSecurityException e) {\n    // includes unavailable-CRL outcomes when policy is DENY\n    LOGGER.warn(\"Revocation status unavailable for [{}]\", CertUtils.toString(cert), e);\n}","preventionTips":["Confirm CRL distribution point URLs are reachable from the CAS server (curl them).","Explicitly set the unavailable-CRL policy (allow vs deny) rather than relying on defaults.","Monitor CRL fetch failures with alerts on the distribution point host.","Configure OCSP as a secondary revocation source when CRLs may be missing."],"tags":["x509","crl","revocation","certificate"],"backgroundTag":"empty-result-set","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"}