apereo/cas · error · BeanCreationException

Could not decode provided Entity Certificate file

Error message

Could not decode provided Entity Certificate file 

What it means

getEntityCertificate() wraps the whole decode of the entity certificate resource in a try/catch and rethrows any failure as BeanCreationException('Could not decode provided Entity Certificate file <resource>', cause). This means the file could not be read or was not parseable as an X509 certificate (unsupported or corrupt PEM/DER content, or an I/O error). The original exception is preserved as the cause.

Solutions

  1. Check the path in the error message: verify the file exists and is readable at that exact location (ls -l).
  2. Validate the file decodes as a certificate: openssl x509 -in <file> -text -noout; fix contents if it is a key, CSR, or bundle.
  3. Re-copy/export the certificate in PEM (BEGIN CERTIFICATE) or DER form if it is corrupt or truncated.
  4. Fix mount/permission issues (chmod 644, correct Docker volume mount) if the file is missing at runtime.

Example fix

// before: resource points to a private-key PEM
val entityResource = new FileSystemResource("/etc/cas/idp.key")
// after: point to the actual certificate
val entityResource = new FileSystemResource("/etc/cas/idp.crt")
Defensive patterns

Strategy: try-catch

Validate before calling

// validate readability and decodability before configuring the bean
try (var is = entityResource.getInputStream()) {
    if (X509Support.decodeCertificates(is).isEmpty()) {
        throw new IllegalStateException("No certificate could be decoded from " + entityResource.getDescription());
    }
} catch (Exception e) {
    throw new IllegalStateException("Entity certificate missing or unparseable: " + entityResource, e);
}

Try / catch

try {
    credentialFactory.getObject();
} catch (BeanCreationException e) {
    if (e.getMessage().startsWith("Could not decode provided Entity Certificate file")) {
        // inspect e.getCause(): IOException => path/permissions; CertificateException => bad content
        logger.error("Fix entityCertificate path or PEM content", e.getCause());
    }
    throw e;
}

Prevention

When it happens

Trigger: entityResource is configured, but entityResource.getInputStream() throws (missing/unreadable file) or X509Support.decodeCertificates() throws (empty file, garbage bytes, non-certificate PEM block, unsupported DER encoding) inside getEntityCertificate().

Common situations: Typo in the certificate path or wrong working directory; Docker volume not mounted so the file is absent; file contains the private key PEM or a CSR instead of a certificate; file truncated by a bad copy; permissions deny read; using a .p12/.jks binary where a PEM cert is expected.

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/0829093dc1c4809a. 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:129

    @Override
    public Class<?> getObjectType() {
        return BasicX509Credential.class;
    }

    private X509Certificate getEntityCertificate() {
        if (null == entityResource) {
            return null;
        }
        try {
            val certs = X509Support.decodeCertificates(entityResource.getInputStream());
            if (certs.size() > 1) {
                throw new BeanCreationException("Configuration element indicated an entityCertificate,"
                    + " but multiple certificates were decoded");
            }
            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;

View on GitHub (pinned to e7288fc434)