apereo/cas · warning

CRL data expired on [ ]

Error message

CRL data expired on [{}]

What it means

Logged when one or more retrieved CRLs have passed their nextUpdate timestamp (CertUtils.isExpired). Each expired CRL is collected and reported with its nextUpdate date. Expiration itself is only a warning here; if ALL CRLs are expired, the expiredCRLPolicy is applied (see the next message).

Solutions

  1. Refresh the CRL: re-download from the CA's distribution point or update the local resource file.
  2. Check server clock/NTP sync ('timedatectl') to rule out skew.
  3. Configure CRL caching with a TTL shorter than the CA's CRL publish interval.
  4. Adjust the expired-CRL policy (allow/deny) if expired-but-usable CRLs should be tolerated, understanding the security tradeoff.

Example fix

// before
cas.authn.x509.crl.resource.location=file:/etc/cas/crls/ca.crl
// after
# automate refresh (cron/systemd timer) so nextUpdate never lapses
0 * * * * curl -s https://crl.example.com/ca.crl -o /etc/cas/crls/ca.crl
Defensive patterns

Strategy: retry

Validate before calling

X509CRL crl = /* fetched */;
if (crl.getNextUpdate() != null && crl.getNextUpdate().toInstant().isBefore(java.time.Instant.now())) {
    // refresh CRL before calling check()
}

Type guard

boolean isStale = Optional.ofNullable(crl.getNextUpdate())
        .map(d -> d.toInstant().isBefore(Instant.now()))
        .orElse(true);

Try / catch

try {
    checker.check(cert);
} catch (GeneralSecurityException e) {
    // expired-CRL policy (e.g. DENY) rejected the request
    LOGGER.warn("CRL expired; attempt refresh and retry once", e);
}

Prevention

When it happens

Trigger: AbstractCRLRevocationChecker.check() fetches CRLs whose thisUpdate/nextUpdate window has lapsed — i.e. the CA has not republished the CRL since nextUpdate passed.

Common situations: Stale CRL files cached on disk or in an HTTP cache past their validity window; an offline/broken CA that stopped publishing CRL updates; clock skew on the CAS server making valid CRLs appear expired.

Related errors


AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08). Data as JSON: /api/errors/25630f16ac22415b. 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:72

        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);

            val revokedCrls = crls.stream().map(crl -> crl.getRevokedCertificate(cert)).filter(Objects::nonNull).toList();
            if (revokedCrls.size() == crls.size()) {
                val entry = revokedCrls.getFirst();
                LOGGER.warn("All CRL entries have been revoked. Rejecting the first entry [{}]", entry);
                throw new RevokedCertificateException(entry);
            }

View on GitHub (pinned to e7288fc434)