apereo/cas · warning

CRL data is not available for

Error message

CRL data is not available for [{}]

What it means

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.

Solutions

  1. Verify the CRL distribution point URL is reachable from the CAS server: 'curl -v <crlDP-url>'.
  2. Set cas.authn.x509.crl.* / unavailable-CRL-policy explicitly (allow or deny) so behavior is intentional.
  3. Configure a fetcher/cache (e.g. ResourceCRLFetcher, CRL distribution point caching) or point CAS at an OCSP responder instead.
  4. If the certificate legitimately has no CRLDP, switch to OCSP-based checking or disable revocation for that CA.

Example fix

// before (cas.properties)
cas.authn.x509.crl.revocation-policy=ALLOW
// after
cas.authn.x509.crl.revocation-policy=DENY
cas.authn.x509.crl.fetcher=resource
cas.authn.x509.crl.resource.location=file:/etc/cas/crls/ca.crl
Defensive patterns

Strategy: validation

Validate before calling

String crlDp = ""; // extract from cert CRL distribution points extension
if (crlDp == null || crlDp.isBlank()) {
    throw new IllegalStateException("Certificate has no CRL distribution point; enable OCSP or skip revocation");
}

Type guard

if (crls == null || crls.isEmpty()) { /* handle unavailable-CRL case explicitly before check() */ }

Try / catch

try {
    checker.check(cert);
} catch (RevokedCertificateException e) {
    throw e;
} catch (GeneralSecurityException e) {
    // includes unavailable-CRL outcomes when policy is DENY
    LOGGER.warn("Revocation status unavailable for [{}]", CertUtils.toString(cert), e);
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.

Related errors


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

Appendix: source

Thrown at support/cas-server-support-x509-core/src/main/java/org/apereo/cas/adaptors/x509/authentication/revocation/checker/AbstractCRLRevocationChecker.java:65

     *                             that produces the cert.
     * @param unavailableCRLPolicy the unavailable crl policy
     * @param expiredCRLPolicy     the expired crl policy
     */
    protected AbstractCRLRevocationChecker(final boolean checkAll,
                                        final RevocationPolicy<Void> unavailableCRLPolicy,
                                        final RevocationPolicy<X509CRL> expiredCRLPolicy) {
        this.checkAll = checkAll;
        this.unavailableCRLPolicy = Objects.requireNonNullElseGet(unavailableCRLPolicy, DenyRevocationPolicy::new);
        this.expiredCRLPolicy = Objects.requireNonNullElseGet(expiredCRLPolicy, () -> new ThresholdExpiredCRLRevocationPolicy(0));
    }

    @Override
    public void check(@NonNull final X509Certificate cert) throws GeneralSecurityException {
        LOGGER.debug("Evaluating certificate revocation status for [{}]", CertUtils.toString(cert));
        val crls = getCRLs(cert);

        if (crls == null || crls.isEmpty()) {
            LOGGER.warn("CRL data is not available for [{}]", CertUtils.toString(cert));
            this.unavailableCRLPolicy.apply(null);
            return;
        }

        val expiredCrls = new ArrayList<X509CRL>(crls.size());
        crls.stream().filter(CertUtils::isExpired).forEach(crl -> {
            LOGGER.warn("CRL data expired on [{}]", crl.getNextUpdate());
            expiredCrls.add(crl);
        });

        if (crls.size() == expiredCrls.size()) {
            LOGGER.warn("All CRLs retrieved have expired. Applying CRL expiration policy...");
            for (val crl : expiredCrls) {
                this.expiredCRLPolicy.apply(crl);
            }
        } else {
            crls.removeAll(expiredCrls);
            LOGGER.debug("Valid CRLs [{}] found that are not expired yet", crls);

View on GitHub (pinned to e7288fc434)