apereo/cas · critical · BeanCreationException

No Certificates provided

Error message

No Certificates provided

What it means

BasicX509CredentialFactoryBean.getObject throws BeanCreationException because the factory bean was constructed without any certificates configured. It builds a BasicX509Credential (for SAML signing/encryption) and requires at least one certificate; an empty certificate list makes the bean impossible to create.

Solutions

  1. Set the certificates (and entity certificate) property on the BasicX509CredentialFactoryBean definition, or the cas.* SAML signing certificate configuration that populates it.
  2. Verify the keystore/certificate file exists and is readable by the CAS process in the target environment.
  3. Check for unresolved property placeholders (e.g. ${cas.saml...}) in the bean configuration — unresolved values may leave the list empty.
  4. Re-run certificate provisioning/import steps so the certificate resource contains at least one entry.

Example fix

// before
@Bean
public BasicX509CredentialFactoryBean credential() { return new BasicX509CredentialFactoryBean(); }
// after
@Bean
public BasicX509CredentialFactoryBean credential() {
    var fb = new BasicX509CredentialFactoryBean();
    fb.setCertificates(List.of(new ClassPathResource("saml-signing.crt")));
    fb.setPrivateKey(new ClassPathResource("saml-signing.key"));
    return fb;
}
Defensive patterns

Strategy: validation

Validate before calling

// Before constructing the factory bean, verify the certificate resource is present and non-empty
Resource cert = new FileSystemResource(keystorePath);
if (!cert.exists() || cert.contentLength() == 0) {
    throw new IllegalStateException("SAML certificate resource missing or empty: " + keystorePath);
}

Try / catch

try { BasicX509Credential credential = factoryBean.getObject(); }
catch (BeanCreationException e) {
    if (e.getMessage().contains("No Certificates provided")) {
        logger.error("SAML certificate configuration is empty; check certificate/keystore settings");
    }
    throw e;
}

Prevention

When it happens

Trigger: Spring bean definition of BasicX509CredentialFactoryBean with no certificates/certificate list property set; the configured keystore resource is empty or failed to load yielding zero certificates; property placeholders resolving to nothing so the certificate collection stays empty.

Common situations: SAML metadata/signing config referencing a keystore path that does not exist or is unreadable at runtime; typo in the property feeding certificates so it resolves to empty; provisioning step that installs the certificate was skipped in the deployment environment.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


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

     * Names for the key represented by the credential.
     */
    private List<String> keyNames;

    /**
     * Identifier for the owner of the credential.
     */
    private String entityID;

    /**
     * The privateKey Password (if any).
     */
    private char[] privateKeyPassword;

    @Override
    public BasicX509Credential getObject() throws Exception {
        val certificates = getCertificates();
        if (certificates.isEmpty()) {
            throw new BeanCreationException("No Certificates provided");
        }

        var entityCertificate = getEntityCertificate();
        if (null == entityCertificate) {
            entityCertificate = certificates.getFirst();
        }

        val privateKey = getPrivateKey();
        var credential = (BasicX509Credential) null;
        if (null == privateKey) {
            credential = new BasicX509Credential(entityCertificate);
        } else {
            credential = new BasicX509Credential(entityCertificate, privateKey);

            if (!KeySupport.matchKeyPair(entityCertificate.getPublicKey(), privateKey)) {
                throw new BeanCreationException("Public and private keys do not match");
            }
        }

View on GitHub (pinned to e7288fc434)