apereo/cas · error
SAML metadata resolver
Error message
SAML metadata resolver [{}] obtained from the cache is unable to produce/resolve valid metadata from [{}]. Metadata resolver cache entry with key [{}] has been invalidated. What it means
A SamlException thrown by SamlRegisteredServiceDefaultCachingMetadataResolver.execute when a cached metadata resolver result is invalid. If the resolver cannot produce exactly one SPSSODescriptor for the requested criteria, CAS invalidates the cache entry and throws because no valid SAML metadata resolver exists for the requested service/entity. Typically indicates the cached metadata lacks the expected SP role descriptor.
Solutions
- Verify the service's entityID (serviceId) actually exists as an EntityDescriptor with an SPSSODescriptor in the configured metadataLocation.
- Inspect the metadata XML at metadataLocation; regenerate/re-upload correct SP metadata.
- Invalidate/flush the metadata resolver cache (or restart) so the invalid entry is rebuilt from source.
- Confirm metadata signing/refresh settings so the underlying resolver re-fetches current metadata instead of serving a broken cached copy.
- Enable DEBUG logging for org.apereo.cas.support.saml.metadata.cache to trace which resolver/cache key failed.
Example fix
// before: entityID not present in metadata, causing invalid cached result
setServiceId("https://sp.example.org/shibboleth") // no such entity in metadata
// after: use the entityID declared in the SP metadata file
setServiceId("https://sp.example.org/sp") // matches <EntityDescriptor entityID=...> with SPSSODescriptor Defensive patterns
Strategy: try-catch
Validate before calling
// Validate that the entity has an SPSSODescriptor before requesting a cached resolver
var crit = new CriteriaSet(
new EntityIdCriterion(service.getServiceId()),
new EvaluableEntityRoleEntityDescriptorCriterion(SPSSODescriptor.DEFAULT_ELEMENT_NAME));
if (metadataResolver.resolveSingle(crit) == null) {
throw new SamlException("Metadata for " + service.getServiceId() + " contains no SPSSODescriptor");
} Try / catch
try {
var result = cachingResolver.resolve(metadataLocation, criteriaSet);
} catch (SamlException e) {
LOGGER.error("No valid metadata resolver for {}: verify entityID and SPSSODescriptor in metadataLocation", metadataLocation, e);
// evict cache entry and/or surface an actionable error to the SP flow
} Prevention
- Confirm the entityID in the service definition matches an EntityDescriptor with an SPSSODescriptor in the metadata source
- Validate metadata files with a schema/role check before uploading them as metadataLocation
- Flush the metadata cache after updating upstream metadata
- Enable DEBUG logging for the metadata cache when diagnosing invalid cached resolvers
When it happens
Trigger: Querying the caching metadata resolver (getMetadataResolverForSamlRegisteredService / resolve paths) with a CriteriaSet for a service whose metadata does not contain an SPSSODescriptor, or whose cached resolver result was marked invalid (result.isValid() == false).
Common situations: SP metadata uploaded/published without an SPSSODescriptor (e.g. IdP-only metadata file); metadataLocation pointing at the wrong entity's metadata; cached entry went stale after upstream metadata changed; entityID in the service config does not match any EntityDescriptor in the metadata.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Unable to locate a valid SAML metadata resolver for to…
- Skipped registration of
- 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…
AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08).
Data as JSON: /api/errors/a445ab88451dbeb0.
Report an issue: GitHub.
Appendix: source
Thrown at support/cas-server-support-saml-idp-metadata/src/main/java/org/apereo/cas/support/saml/services/idp/metadata/cache/SamlRegisteredServiceDefaultCachingMetadataResolver.java:87
public CachedMetadataResolverResult resolve(final SamlRegisteredService service, final CriteriaSet criteriaSet) throws Exception {
val metadataLocation = SpringExpressionLanguageValueResolver.getInstance().resolve(service.getMetadataLocation());
LOGGER.debug("Resolving metadata for [{}] at [{}]", service.getName(), metadataLocation);
val cacheKey = new SamlRegisteredServiceCacheKey(service, criteriaSet);
return FunctionUtils.doAndRetry(
new Retryable<>() {
@Override
public @Nullable CachedMetadataResolverResult execute() throws Throwable {
LOGGER.debug("Locating cached metadata resolver using key [{}] for service [{}].",
cacheKey.getId(), service.getName());
val queryResult = locateAndCacheMetadataResolver(service, criteriaSet, cacheKey);
val result = isMetadataResolverAcceptable(queryResult, criteriaSet);
if (!result.isValid()) {
val criteria = new EvaluableEntityRoleEntityDescriptorCriterion(SPSSODescriptor.DEFAULT_ELEMENT_NAME);
val count = Iterables.size(result.getResult().getMetadataResolver().resolve(new CriteriaSet(criteria)));
if (count == 1) {
invalidate(service, criteriaSet);
}
LOGGER.warn("SAML metadata resolver [{}] obtained from the cache is "
+ "unable to produce/resolve valid metadata from [{}]. Metadata resolver cache entry with key [{}] "
+ "has been invalidated.", result.getResult().getMetadataResolver().getId(), metadataLocation, cacheKey.getId());
throw new SamlException("Unable to locate a valid SAML metadata resolver for "
+ metadataLocation + " to locate " + criteriaSet);
}
return queryResult.getResult();
}
},
casProperties.getAuthn().getSamlIdp().getMetadata().getCore().getMaximumRetryAttempts());
}
@Override
public void invalidate() {
LOGGER.trace("Invalidating cache, removing all metadata resolvers");
cache.invalidateAll();
}
@OverrideView on GitHub (pinned to e7288fc434)