apereo/cas · critical · BeanCreationException

Could not decode provided CRL file

Error message

Could not decode provided CRL file 

What it means

BasicX509CredentialFactoryBean.getCRLs() reads each configured CRL resource and decodes it via X509Support.decodeCRLs(). If the stream cannot be opened or the bytes are not a parseable X.509 CRL (CRLDEF/PEM/DER), it wraps the failure in a Spring BeanCreationException, aborting creation of the credential bean.

Solutions

  1. Verify every configured CRL resource path/URL resolves and is readable by the CAS process (test with cat/curl using the exact configured value).
  2. Validate the file is a real CRL: run `openssl crl -in crl.pem -noout -text` (or `-inform DER`) and fix the format/encoding if it fails.
  3. If fetched over HTTP, confirm the URL returns the CRL itself, not an HTML error page; re-download from the issuer.
  4. Catch the BeanCreationException during startup and correct the resource; the bean will keep failing until the CRL resource is valid.

Example fix

// before
cas.authn.saml.sp.crl-resource=file:/etc/cas/crls/old-ca.crl   // file missing/corrupt

// after
# validate first: openssl crl -in /etc/cas/crls/ca.crl -noout -text
cas.authn.saml.sp.crl-resource=file:/etc/cas/crls/ca.crl
Defensive patterns

Strategy: validation

Validate before calling

// before wiring the credential bean
for (Resource crl : crlResources) {
    try (var is = crl.getInputStream()) {
        var crls = X509Support.decodeCRLs(is);
        if (crls.isEmpty()) throw new IllegalStateException("No CRLs decoded from " + crl.getDescription());
    }
}

Try / catch

try {
    credentialFactoryBean.getObject();
} catch (BeanCreationException e) {
    logger.error("CRL resource invalid: {}", e.getCause() != null ? e.getCause().getMessage() : e.getMessage());
}

Prevention

When it happens

Trigger: crlResources contains a resource whose getInputStream() fails (file missing, unreadable, bad URL) or whose content is not a valid CRL that X509Support.decodeCRLs() can parse.

Common situations: cas.authn.saml.sp.crlResource-style config pointing at a typo'd path, an empty or HTML error page downloaded instead of a CRL, a PEM file with wrong headers, or a CRL file that expired/was replaced by corrupt content.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


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

Appendix: source

Thrown at support/cas-server-support-saml-core-api/src/main/java/org/apereo/cas/support/saml/util/credential/BasicX509CredentialFactoryBean.java:175

            throw new BeanCreationException("Could not decode provided KeyFile " + privateKeyResource.getDescription(), e);
        }
    }

    @Override
    public boolean isSingleton() {
        return true;
    }

    private List<X509CRL> getCRLs() {
        if (null == crlResources) {
            return null;
        }
        val crls = new LazyList<X509CRL>();
        for (val crl : crlResources) {
            try (val is = crl.getInputStream()) {
                crls.addAll(X509Support.decodeCRLs(is));
            } catch (final Exception e) {
                throw new BeanCreationException("Could not decode provided CRL file " + crl.getDescription(), e);
            }
        }
        return crls;
    }
}

View on GitHub (pinned to e7288fc434)