apereo/cas · warning
Failed to locate the signing key
Error message
Failed to locate the signing key [{}] for [{}] What it means
When configuring the MDUI metadata resolver chain, CAS builds a signature validation filter from the configured signing key. If SamlUtils.buildSignatureValidationFilter returns null for the given key/reference, this warning is logged and the metadata resource is excluded (addResource = false).
Solutions
- Verify the signing key resource path exists and is readable by CAS (ResourceUtils.doesResourceExist).
- Check the key format is one OpenSAML's SignatureValidationFilter supports (X.509 PEM cert or keystore).
- Rebuild the signing key path or embed the certificate in metadata trust.
- If signature validation is not needed, remove the signing key config so the filter branch is skipped.
Example fix
// before cas.saml-metadata-ui.signing-key[0]=file:/etc/cas/mdui/missing-cert.pem // after cas.saml-metadata-ui.signing-key[0]=file:/etc/cas/mdui/federation-signer.pem
Defensive patterns
Strategy: validation
Validate before calling
var keyRes = applicationContext.getResource(signingKey);
if (!keyRes.exists()) {
LOGGER.warn("Signing key missing: {}", signingKey);
// fix path or disable signature validation
} Prevention
- Verify signing key paths exist in the deployed image before startup.
- Use standard PEM/keystore formats supported by OpenSAML.
- Add a startup health check that loads configured signing keys.
When it happens
Trigger: configureResource has a signing key configured for the metadataReference, but the key cannot be loaded/located — bad path, unreadable keystore/cert file, unsupported key format — so buildSignatureValidationFilter yields null.
Common situations: Typo in signing key path in cas.saml-metadata-ui config; certificate file missing in container image; key in unsupported format (e.g. DER vs PEM); wrong keystore password handled upstream producing null instead of throw.
Understand the failure class
Background: "missing required config value" errors: why libraries refuse to start when a configuration key is empty, unset, or blank — this error's family across 48 libraries.
Related errors
- Unable to use 'none' for the user-info signing algorithm
- Unable to use 'none' as ID token signing algorithm
- Unable to determine entity id to fetch metadata via MDQ for
- Found configuration property as a Map
- Ticket registry encryption/signing for
AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08).
Data as JSON: /api/errors/05965c228910608a.
Report an issue: GitHub.
Appendix: source
Thrown at support/cas-server-support-saml-mdui/src/main/java/org/apereo/cas/config/SamlMetadataUIConfiguration.java:89
val arr = Splitter.on(DEFAULT_SEPARATOR).splitToList(entry);
val metadataReference = arr.getFirst();
val signingKey = arr.size() > 1 ? arr.get(1) : null;
val filters = new ArrayList<MetadataFilter>();
if (casProperties.getSamlMetadataUi().getMaxValidity() > 0) {
val filter = new RequiredValidUntilFilter();
filter.setMaxValidityInterval(Duration.ofSeconds(casProperties.getSamlMetadataUi().getMaxValidity()));
filter.initialize();
filters.add(filter);
}
var addResource = true;
if (StringUtils.isNotBlank(signingKey)) {
val sigFilter = SamlUtils.buildSignatureValidationFilter(applicationContext, signingKey);
if (sigFilter != null) {
sigFilter.setRequireSignedRoot(casProperties.getSamlMetadataUi().isRequireSignedRoot());
sigFilter.initialize();
filters.add(sigFilter);
} else {
LOGGER.warn("Failed to locate the signing key [{}] for [{}]", signingKey, metadataReference);
addResource = false;
}
}
chain.setFilters(filters);
if (addResource && (ResourceUtils.isUrl(metadataReference) || ResourceUtils.doesResourceExist(metadataReference))) {
val resource = applicationContext.getResource(metadataReference);
resources.put(resource, chain);
} else {
LOGGER.warn("Skipping metadata [{}]; Either the resource cannot be retrieved or its signing key is missing", metadataReference);
}
}));
}
@ConditionalOnMissingBean(name = "chainingSamlMetadataUIMetadataResolverAdapter")
@Bean
@RefreshScope(proxyMode = ScopedProxyMode.DEFAULT)
public MetadataResolverAdapter chainingSamlMetadataUIMetadataResolverAdapter(
final CasConfigurationProperties casProperties,View on GitHub (pinned to e7288fc434)