apereo/cas · error · BeanCreationException

Could not decode provided CertificateFile:

Error message

Could not decode provided CertificateFile: 

What it means

getCertificates() iterates the configured certificateResources and decodes each into X509 certificates for the entity certificate chain. If any resource cannot be read or decoded as a certificate, bean creation is aborted with BeanCreationException('Could not decode provided CertificateFile: <resource>', cause). The failing resource is named in the message and the underlying exception kept as cause.

Solutions

  1. Identify the failing file from the message (r.getDescription()) and confirm it exists and is readable.
  2. Validate it with openssl x509 -in <file> -text -noout; remove or replace files that are not certificates.
  3. Re-export/re-download the intermediate/root CA certificate if it is truncated or corrupt.
  4. Remove non-certificate files (keys, CRLs) from the certificates list — CRLs belong in the CRL configuration.

Example fix

# before: certificates list contains a corrupt backup file
# cas.authn.saml.idp.credential.certificates=intermediate.crt,root.crt.bak
# after
cas.authn.saml.idp.credential.certificates=file:/etc/cas/chain/intermediate.pem,file:/etc/cas/chain/root.pem
Defensive patterns

Strategy: validation

Validate before calling

// validate every chain resource before configuring the bean
for (var r : certificateResources) {
    try (var is = r.getInputStream()) {
        if (X509Support.decodeCertificates(is).isEmpty()) {
            throw new IllegalStateException("No certificate decoded from " + r.getDescription());
        }
    }
}

Try / catch

try {
    credentialFactory.getObject();
} catch (BeanCreationException e) {
    if (e.getMessage().startsWith("Could not decode provided CertificateFile:")) {
        // message names the offending resource; remove/fix that file and retry
        logger.error("Bad certificate chain entry: {}", e.getMessage(), e.getCause());
    }
    throw e;
}

Prevention

When it happens

Trigger: A resource in certificateResources returns an InputStream that throws on read, or X509Support.decodeCertificates(is) throws for that stream (empty/corrupt/non-certificate content) while building the chain in getCertificates().

Common situations: One entry in a multi-file chain list points at a nonexistent or renamed file; an intermediate CA file is empty or truncated; a private key or CRL file accidentally listed among the certificates; wrong permissions on one file in a directory of chain certs.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


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

            }
            return certs.iterator().next();
        } catch (final Exception e) {
            throw new BeanCreationException("Could not decode provided Entity Certificate file "
                + entityResource.getDescription(), e);
        }
    }

    private List<X509Certificate> getCertificates() {
        if (certificateResources == null) {
            return new ArrayList<>();
        }

        val certificates = new LazyList<X509Certificate>();
        for (val r : certificateResources) {
            try (val is = r.getInputStream()) {
                certificates.addAll(X509Support.decodeCertificates(is));
            } catch (final Exception e) {
                throw new BeanCreationException("Could not decode provided CertificateFile: " + r.getDescription(), e);
            }
        }
        return certificates;
    }

    private PrivateKey getPrivateKey() {
        if (null == privateKeyResource) {
            return null;
        }
        try (val is = privateKeyResource.getInputStream()) {
            return KeySupport.decodePrivateKey(is, getPrivateKeyPassword());
        } catch (final Exception e) {
            throw new BeanCreationException("Could not decode provided KeyFile " + privateKeyResource.getDescription(), e);
        }
    }

    @Override
    public boolean isSingleton() {

View on GitHub (pinned to e7288fc434)