{"record":{"id":"b3a5d4c01c3b7d42","repo":"apereo/cas","slug":"no-metadata-could-be-found-for","errorCode":null,"errorMessage":"No metadata could be found for [{}]","messagePattern":"No metadata could be found for \\[(.+?)\\]","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"support/cas-server-support-saml-idp-web/src/main/java/org/apereo/cas/support/saml/web/idp/profile/AbstractSamlIdPProfileHandlerController.java","lineNumber":408,"sourceCode":"        LOGGER.debug(\"Checking for single sign-on participation for issuer [{}]\", issuer);\n        val ssoAvailable = ssoStrategy.supports(ssoRequest) && ssoStrategy.isParticipating(ssoRequest);\n        return ssoAvailable ? Optional.of(ticketGrantingTicket) : Optional.empty();\n    }\n\n    protected Pair<SamlRegisteredService, SamlRegisteredServiceMetadataAdaptor> verifySamlAuthenticationRequest(\n        final Pair<? extends RequestAbstractType, MessageContext> authenticationContext,\n        final HttpServletRequest request) throws Throwable {\n        val authnRequest = (AuthnRequest) authenticationContext.getKey();\n        val issuer = SamlIdPUtils.getIssuerFromSamlObject(authnRequest);\n        LOGGER.debug(\"Located issuer [{}] from authentication request\", issuer);\n\n        val registeredService = verifySamlRegisteredService(issuer, request);\n        LOGGER.debug(\"Fetching SAML2 metadata adaptor for [{}]\", issuer);\n        val adaptor = SamlRegisteredServiceMetadataAdaptor.get(\n            configurationContext.getSamlRegisteredServiceCachingMetadataResolver(), registeredService, authnRequest);\n\n        if (adaptor.isEmpty()) {\n            LOGGER.warn(\"No metadata could be found for [{}]\", issuer);\n            throw UnauthorizedServiceException.denied(\"Cannot find metadata linked to %s\".formatted(issuer));\n        }\n\n        val facade = adaptor.get();\n        verifyAuthenticationContextSignature(authenticationContext, request, authnRequest, facade, registeredService);\n        val binding = determineProfileBinding(authenticationContext, request);\n        val acs = SamlIdPUtils.determineEndpointForRequest(Pair.of(authnRequest, authenticationContext.getRight()), facade, binding);\n        LOGGER.debug(\"Determined SAML2 endpoint for authentication request as [{}]\",\n            StringUtils.defaultIfBlank(acs.getResponseLocation(), acs.getLocation()));\n\n        configurationContext.getOpenSamlConfigBean().logObject(authnRequest);\n        return Pair.of(registeredService, facade);\n    }\n\n    protected void verifyAuthenticationContextSignature(final Pair<? extends SignableSAMLObject, MessageContext> authenticationContext,\n                                                        final HttpServletRequest request, final RequestAbstractType authnRequest,\n                                                        final SamlRegisteredServiceMetadataAdaptor adaptor,\n                                                        final SamlRegisteredService registeredService) throws Throwable {","sourceCodeStart":390,"sourceCodeEnd":426,"githubUrl":"https://github.com/apereo/cas/blob/e7288fc434b4f4505b8452e1a57e8fb3111bb863/support/cas-server-support-saml-idp-web/src/main/java/org/apereo/cas/support/saml/web/idp/profile/AbstractSamlIdPProfileHandlerController.java#L390-L426","documentation":"Although the SP was found in the CAS service registry, no SAML metadata adaptor (metadata document) matching the issuer and the incoming AuthnRequest could be resolved from the caching metadata resolver. CAS cannot validate or process the request without the SP's metadata, so it throws UnauthorizedServiceException.denied. This typically means the metadata location configured on the service is wrong, unreachable, or does not contain the entityID.","triggerScenarios":"verifySamlAuthenticationRequest calls SamlRegisteredServiceMetadataAdaptor.get(resolver, registeredService, authnRequest) and the returned Optional is empty — i.e. metadataCriteria on the service points to an invalid/unreachable URL or file, or the metadata aggregate exists but lacks an EntityDescriptor for the issuer entityID.","commonSituations":"metadataLocation URL points to a federation aggregate that expired (validUntil passed); typo'd entityID so no EntityDescriptor matches; metadata file not present at the configured path; MDQ/federation server down or returning 404; metadata cached stale after the SP rotated entityID or certificates.","solutions":["Verify the SamlRegisteredService's metadataLocation (URL/file/MDQ) is correct, reachable from the CAS server, and returns valid SAML metadata.","Confirm the issuer entityID in the AuthnRequest exactly matches an EntityDescriptor entityID inside that metadata (check for typos and case).","Check the metadata cache: restart or force metadata refresh if validUntil/backoff caused stale or skipped refreshes; look for refresh errors in logs.","If using an aggregate, validate it with an XML signature/validity check; expired aggregates are dropped by the resolver.","Enable DEBUG logging on org.apereo.cas.support.saml to trace the metadata resolution attempt."],"exampleFix":"// before: metadataLocation points at a dead host\n\"metadataLocation\": \"https://old-federation.example.org/metadata/sp.xml\"\n// after: correct, reachable metadata containing the SP entityID\n\"metadataLocation\": \"https://metadata.example.org/sp-metadata.xml\"","handlingStrategy":"validation","validationCode":"// Pre-check that metadata resolves for the SP\nval adaptor = SamlRegisteredServiceMetadataAdaptor.get(resolver, registeredService, authnRequest);\nif (adaptor.isEmpty()) throw new IllegalStateException(\"No SAML metadata for issuer: \" + issuer);","typeGuard":"boolean hasMetadata(SamlRegisteredService svc) { return svc != null && StringUtils.isNotBlank(svc.getMetadataLocation()); }","tryCatchPattern":"try {\n    verifySamlAuthenticationRequest(...);\n} catch (UnauthorizedServiceException e) {\n    LOGGER.error(\"Metadata missing for issuer {}\", issuer, e);\n    // surface 'SP metadata not configured' to operators\n}","preventionTips":["Validate metadataLocation URLs from the CAS server's network (curl the URL on the host).","Set up metadata refresh monitoring; alert on expired validUntil aggregates.","Ensure SP entityID strings match metadata exactly (copy-paste, not retype)."],"tags":["saml","metadata","unauthorized-service","cas"],"backgroundTag":"resource-not-found","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"}