apereo/cas · warning
Resource [ ] cannot be located
Error message
Resource [{}] cannot be located What it means
SamlUtils.buildSignatureValidationFilter() loads SAML metadata signing/validation material from the given Resource. If the resource does not exist or is unreadable, it logs this warning and returns null, meaning no signature validation filter will be built. Callers must handle the null filter or metadata signatures will not be validated as intended.
Solutions
- Verify the configured resource path exists and is readable by the CAS process (check container volume mounts)
- Fix the cas.authn.saml.* signature-metadata property to point at the correct file/classpath location
- Handle the null return: decide whether failing fast (throw) is safer than silently skipping signature validation
- Re-deploy including the resource if it was supposed to be on the classpath
Example fix
// before: silently null filter
val filter = SamlUtils.buildSignatureValidationFilter(resource);
// after: guard first
if (!ResourceUtils.doesResourceExist(resource)) {
throw new FileNotFoundException(resource.getFilename());
}
val filter = SamlUtils.buildSignatureValidationFilter(resource); Defensive patterns
Strategy: validation
Validate before calling
// precheck the resource before building the filter
if (!ResourceUtils.doesResourceExist(signatureResource)) {
throw new FileNotFoundException(signatureResource.getDescription());
} Type guard
function hasFilter(f) { return f != null; } Try / catch
val filter = SamlUtils.buildSignatureValidationFilter(res);
if (filter == null) throw new IllegalStateException('signature metadata missing: ' + res); Prevention
- Verify the signature resource path exists in every deployment environment
- Include classpath metadata files in the build artifact
- Fail fast on null filter instead of silently skipping signature validation
When it happens
Trigger: Passing a signature metadata Resource whose file path is wrong, the file is missing on disk, or the classpath:/http: location cannot be resolved by ResourceUtils.doesResourceExist.
Common situations: Typo in the signature metadata file path in cas.authn.saml properties; the signing certificate/metadata file was moved or deleted after deployment; running in a container where the mounted metadata volume is absent; classpath resource not packaged into the WAR.
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
- Resource does not exist or is unreadable
- No assertion consumer service could be found for entity
- Endpoint for is not available or does not define a binding…
- Endpoint for does not define a binding or location for…
- Metadata directory location cannot be located/created
AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08).
Data as JSON: /api/errors/1c0c2a636bf833c2.
Report an issue: GitHub.
Appendix: source
Thrown at support/cas-server-support-saml-core-api/src/main/java/org/apereo/cas/support/saml/SamlUtils.java:286
try {
val resource = resourceLoader.getResource(signatureResourceLocation);
return buildSignatureValidationFilter(resource);
} catch (final Exception e) {
LOGGER.debug(e.getMessage(), e);
}
return null;
}
/**
* Build signature validation filter if needed.
*
* @param signatureResourceLocation the signature resource location
* @return the metadata filter
* @throws Exception the exception
*/
public static @Nullable SignatureValidationFilter buildSignatureValidationFilter(final Resource signatureResourceLocation) throws Exception {
if (!ResourceUtils.doesResourceExist(signatureResourceLocation)) {
LOGGER.warn("Resource [{}] cannot be located", signatureResourceLocation);
return null;
}
val keyInfoProviderList = new ArrayList<KeyInfoProvider>(4);
keyInfoProviderList.add(new RSAKeyValueProvider());
keyInfoProviderList.add(new DSAKeyValueProvider());
keyInfoProviderList.add(new DEREncodedKeyValueProvider());
keyInfoProviderList.add(new InlineX509DataProvider());
LOGGER.debug("Attempting to resolve credentials from [{}]", signatureResourceLocation);
val credential = buildCredentialForMetadataSignatureValidation(signatureResourceLocation);
LOGGER.info("Successfully resolved credentials from [{}]", signatureResourceLocation);
Objects.requireNonNull(credential, "No credential found");
LOGGER.debug("Configuring credential resolver for key signature trust engine @ [{}]",
credential.getCredentialType().getSimpleName());
val resolver = new StaticCredentialResolver(credential);
val keyInfoResolver = new BasicProviderKeyInfoCredentialResolver(keyInfoProviderList);View on GitHub (pinned to e7288fc434)