{"record":{"id":"598de86766e38e9e","repo":"apereo/cas","slug":"no-metadata-resolvers-could-be-configured-for-serv","errorCode":null,"errorMessage":"No metadata resolvers could be configured for service  with metadata location ","messagePattern":"No metadata resolvers could be configured for service  with metadata location ","errorType":"exception","errorClass":"SamlException","httpStatus":null,"severity":"error","filePath":"support/cas-server-support-saml-idp-metadata/src/main/java/org/apereo/cas/support/saml/services/idp/metadata/cache/SamlRegisteredServiceMetadataResolverCacheLoader.java","lineNumber":45,"sourceCode":" * @since 5.0.0\n */\n@Slf4j\n@RequiredArgsConstructor\npublic class SamlRegisteredServiceMetadataResolverCacheLoader implements CacheLoader<SamlRegisteredServiceCacheKey, CachedMetadataResolverResult> {\n\n    protected final OpenSamlConfigBean configBean;\n\n    protected final HttpClient httpClient;\n    \n    private final SamlRegisteredServiceMetadataResolutionPlan metadataResolutionPlan;\n\n    @Override\n    public CachedMetadataResolverResult load(final SamlRegisteredServiceCacheKey cacheKey) {\n        val metadataResolvers = loadMetadataResolvers(cacheKey);\n        if (metadataResolvers.isEmpty()) {\n            val registeredService = cacheKey.getRegisteredService();\n            val metadataLocation = SpringExpressionLanguageValueResolver.getInstance().resolve(registeredService.getMetadataLocation());\n            throw new SamlException(\"No metadata resolvers could be configured for service \" + registeredService.getName()\n                + \" with metadata location \" + metadataLocation);\n        }\n\n        val metadataResolver = initializeChainingMetadataResolver(metadataResolvers);\n        LOGGER.debug(\"Metadata resolvers active for this request are [{}]\", Objects.requireNonNull(metadataResolvers));\n        return CachedMetadataResolverResult\n            .builder()\n            .cachedInstant(Instant.now(Clock.systemUTC()))\n            .metadataResolver(metadataResolver)\n            .build();\n    }\n\n    protected MetadataResolver initializeChainingMetadataResolver(final List<MetadataResolver> metadataResolvers) {\n        return FunctionUtils.doUnchecked(() -> {\n            val metadataResolver = new ChainingMetadataResolver();\n            metadataResolver.setId(ChainingMetadataResolver.class.getCanonicalName());\n            LOGGER.trace(\"There are [{}] eligible metadata resolver(s) for this request\", metadataResolvers.size());\n            metadataResolver.setResolvers(metadataResolvers);","sourceCodeStart":27,"sourceCodeEnd":63,"githubUrl":"https://github.com/apereo/cas/blob/e7288fc434b4f4505b8452e1a57e8fb3111bb863/support/cas-server-support-saml-idp-metadata/src/main/java/org/apereo/cas/support/saml/services/idp/metadata/cache/SamlRegisteredServiceMetadataResolverCacheLoader.java#L27-L63","documentation":"SamlRegisteredServiceMetadataResolverCacheLoader.load() is the LoadingCache loader producing a CachedMetadataResolverResult for a SamlRegisteredServiceCacheKey. If loadMetadataResolvers() returns an empty list — no configured resolver (resource/HTTP/file/db/etc.) applies to or succeeds for the service — it throws SamlException naming the service and its resolved metadata location.","triggerScenarios":"load() (public) calls loadMetadataResolvers(cacheKey); the result is empty because the registered service's metadataLocation is blank/unresolvable after Spring EL resolution, or no SamlRegisteredServiceMetadataResolver in the chain matches/supports the location scheme.","commonSituations":"Registered service created without a metadataLocation; metadataLocation uses an unsupported scheme (e.g. missing http(s)/file prefix) or a SpEL expression that resolves to empty; metadata resource module not on the classpath so no resolver is registered.","solutions":["Set a valid metadataLocation on the registered service (e.g. file:/etc/cas/metadata/sp-metadata.xml or https://sp.example.com/metadata) and save it.","Confirm the scheme of metadataLocation matches an available resolver (HTTP, filesystem, classpath, JDBC, MongoDB, etc.) and the corresponding CAS module is included in the build.","Check that any SpEL in metadataLocation actually resolves to a non-empty value (log/resolve it manually with SpringExpressionLanguageValueResolver).","Verify metadata resolution for that location manually (curl/file read) to rule out an empty or unreachable source."],"exampleFix":"// before (service registered without location)\n{ \"name\": \"SP\", \"serviceId\": \"^https://sp.example.com\", \"metadataLocation\": \"\" }\n\n// after\n{ \"name\": \"SP\", \"serviceId\": \"^https://sp.example.com\", \"metadataLocation\": \"https://sp.example.com/saml/metadata\" }","handlingStrategy":"validation","validationCode":"// when creating/updating a SAML registered service\nString loc = SpringExpressionLanguageValueResolver.getInstance().resolve(service.getMetadataLocation());\nif (loc == null || loc.isBlank())\n    throw new IllegalArgumentException(\"Service \" + service.getName() + \" needs a concrete metadataLocation\");\nif (!(loc.startsWith(\"http\") || loc.startsWith(\"file\") || loc.startsWith(\"classpath\")))\n    throw new IllegalArgumentException(\"Unsupported metadataLocation scheme: \" + loc);","typeGuard":null,"tryCatchPattern":"try {\n    CachedMetadataResolverResult r = cache.get(cacheKey);\n} catch (SamlException e) {\n    logger.error(\"Service {} metadata misconfigured: {}\", service.getName(), e.getMessage());\n}","preventionTips":["Require metadataLocation at service-registration time via management UI/validation.","Include the CAS module for each metadata scheme you use (file/http/db).","Test SpEL-based metadata locations resolve to non-empty values in a lower environment."],"tags":["saml","metadata","registered-service","resolver","config"],"backgroundTag":"missing-required-config-field","analyzedSha":"e7288fc434b4f4505b8452e1a57e8fb3111bb863","analyzedAt":"2026-09-08T15:39:16.015Z","contentChangedAt":"2026-09-08T15:39:16.015Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}