apereo/cas · warning
Groovy script [ ] does not exist or cannot be loaded
Error message
Groovy script [{}] does not exist or cannot be loaded What it means
GroovySamlRegisteredServiceAttributeReleasePolicy.getAttributesForSamlRegisteredService() executes the configured Groovy script from the script cache to compute released attributes. If the script resource cannot be located or loaded (Optional empty from the cache lookup), it logs this warning and returns an empty attribute map; if no script cache manager exists at all it throws a RuntimeException. Either way no attributes are released from the script.
Solutions
- Verify the script path/URL in the service definition resolves from the CAS server (test with file/classpath resource access) and is readable by the CAS user
- Check the script compiles by executing it standalone or watching startup logs for Groovy compilation errors
- Ensure the Groovy script cache manager is available (correct CAS module/wiring) so the policy does not throw
- Return a valid Map<String,List<Object>> from the script; an empty map is the safe no-attributes contract
Example fix
// before: wrong path in service policy "groovyScript" : "file:/etc/cas/scripts/attr-release.groovy.bak" // after "groovyScript" : "file:/etc/cas/scripts/attr-release.groovy"
Defensive patterns
Strategy: validation
Validate before calling
// check the script resource before configuring the policy
val f = new File('/etc/cas/scripts/attr-release.groovy');
if (!f.isFile() || !f.canRead()) throw new FileNotFoundException(f.getPath()); Type guard
function scriptLoaded(cache, path) { return cache != null && cache.resolveScriptResource(path).isPresent(); } Try / catch
try { attrs = policy.getAttributesInternal(...); }
catch (RuntimeException e) { log.error('Groovy policy failed: no script cache', e); attrs = Map.of(); } Prevention
- Validate script paths after every deploy or service-import
- Give the CAS process read permission on script directories
- Test-compile Groovy scripts in CI before shipping them
- Return Map<String,List<Object>> from scripts to match the policy contract
When it happens
Trigger: A service's attribute release policy references a Groovy script path that does not exist, is misfiled (relative vs classpath/file: URL), or fails to compile/load; or the policy runs without a Groovy script cache manager bean configured.
Common situations: Typo in file:groovy path in the service definition JSON; script not deployed to the CAS server filesystem or classpath; file permissions denying read; moving from inline Groovy to external script after an upgrade; cache manager not initialized in a custom wiring.
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
- Could not locate metadata for
- Script cache manager unavailable to handle LDAP filter
- Missing required principal attribute for claim
- Unable to grant access to
- No Certificates provided
AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08).
Data as JSON: /api/errors/6bf71c4eae26d320.
Report an issue: GitHub.
Appendix: source
Thrown at support/cas-server-support-saml-idp-core/src/main/java/org/apereo/cas/support/saml/services/GroovySamlRegisteredServiceAttributeReleasePolicy.java:57
protected Map<String, List<Object>> getAttributesForSamlRegisteredService(
final Map<String, List<Object>> attributes,
final SamlRegisteredServiceCachingMetadataResolver resolver,
final SamlRegisteredServiceMetadataAdaptor facade,
final EntityDescriptor entityDescriptor,
final RegisteredServiceAttributeReleasePolicyContext context) {
return ApplicationContextProvider.getScriptResourceCacheManager()
.map(cacheMgr -> {
val groovyResource = SpringExpressionLanguageValueResolver.getInstance().resolve(this.groovyScript);
val script = cacheMgr.resolveScriptableResource(groovyResource, groovyResource);
return Optional.ofNullable(script)
.map(Unchecked.function(sc -> {
val args = new Object[]{attributes, context.getRegisteredService(), resolver,
facade, entityDescriptor, context.getApplicationContext(), LOGGER};
return (Map<String, List<Object>>) script.execute(args, Map.class, true);
}))
.orElseGet(() -> {
LOGGER.warn("Groovy script [{}] does not exist or cannot be loaded", groovyScript);
return new HashMap<>();
});
})
.orElseThrow(() -> new RuntimeException("No groovy script cache manager is available to execute attribute mappings"));
}
}
View on GitHub (pinned to e7288fc434)