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
- Set the certificates (and entity certificate) property on the BasicX509CredentialFactoryBean definition, or the cas.* SAML signing certificate configuration that populates it.
- Verify the keystore/certificate file exists and is readable by the CAS process in the target environment.
- Check for unresolved property placeholders (e.g. ${cas.saml...}) in the bean configuration — unresolved values may leave the list empty.
- 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
- Always set at least one certificate (ideally an explicit entity certificate) on the factory bean.
- Validate certificate file existence/readability in startup checks or CI before CAS boots.
- Check that property placeholders feeding the certificate list resolve to real values.
- Include certificate provisioning in deployment playbooks so no environment starts without it.
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.
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- Expired or invalid certificate in metadata for
- Unable to accept certificate
- Public and private keys do not match
- Configuration element indicated an entityCertificate, but…
- Could not decode provided Entity Certificate file
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)