apereo/cas · error · SamlException

Endpoint for is not available or does not define a binding…

Error message

Endpoint for  is not available or does not define a binding for 

What it means

SamlIdPUtils.determineEndpointForRequest() resolves the response endpoint for an AuthnRequest using the requested binding. If after checking metadata ACS, request-supplied ACS, and index-based lookup the endpoint is still null, it throws SamlException indicating the peer entity does not define an endpoint for that binding.

Solutions

  1. Add an AssertionConsumerService entry with the requested Binding (e.g. urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST) and Location to the SP metadata.
  2. Check the AuthnRequest's ProtocolBinding/AssertionConsumerServiceIndex/URL against the metadata and align them.
  3. Refresh the SP metadata in CAS so it reflects the SP's current ACS declarations.
  4. Verify the `binding` parameter passed by the caller matches a binding the SP actually supports.

Example fix

// before
<md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://sp.example.com/acs" index="0"/>

// after
<md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://sp.example.com/acs" index="0" isDefault="true"/>
Defensive patterns

Strategy: validation

Validate before calling

// before responding
boolean hasBinding = adaptor.getAssertionConsumerServices().stream()
    .anyMatch(acs -> binding.equalsIgnoreCase(acs.getBinding()));
if (!hasBinding) {
    logger.warn("SP {} has no ACS for binding {}", adaptor.getEntityId(), binding);
}

Try / catch

try {
    endpoint = SamlIdPUtils.determineEndpointForRequest(authnRequest, adaptor, binding, fromReq, fromMeta, context);
} catch (SamlException e) {
    logger.error("No endpoint for binding {}: {}", binding, e.getMessage());
}

Prevention

When it happens

Trigger: preparePeerEntitySamlEndpointContext() calls determineEndpointForRequest with a binding (e.g. POST or Redirect) for which neither the request's AssertionConsumerServiceURL/index nor the metadata's AssertionConsumerService entries yield a matching endpoint, leaving endpoint null.

Common situations: SP metadata only declares a SOAP or Artifact binding while CAS is asked to respond with POST; AuthnRequest references an ACS index/binding absent from metadata; metadata is stale relative to the SP's current configuration.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08). Data as JSON: /api/errors/98a1a377c78011df. Report an issue: GitHub.

Appendix: source

Thrown at support/cas-server-support-saml-idp-core/src/main/java/org/apereo/cas/support/saml/SamlIdPUtils.java:119

     * @param adaptor      the adaptor
     * @param binding      the binding
     * @return the assertion consumer service
     */
    public static Endpoint determineEndpointForRequest(final Pair<? extends RequestAbstractType, MessageContext> authnContext,
                                                       final SamlRegisteredServiceMetadataAdaptor adaptor,
                                                       final String binding) {
        var endpoint = (Endpoint) null;
        val authnRequest = authnContext.getLeft();
        if (authnRequest instanceof LogoutRequest) {
            endpoint = adaptor.getSingleLogoutService(binding);
        } else {
            val acsEndpointFromReq = getAssertionConsumerServiceFromRequest(authnRequest, binding, adaptor);
            val acsEndpointFromMetadata = adaptor.getAssertionConsumerService(binding);
            endpoint = determineEndpointForRequest(authnRequest, adaptor, binding,
                acsEndpointFromReq, acsEndpointFromMetadata, authnContext.getRight());
        }
        if (endpoint == null) {
            throw new SamlException("Endpoint for " + authnRequest.getSchemaType()
                + " is not available or does not define a binding for " + binding);
        }
        val missingLocation = StringUtils.isBlank(endpoint.getResponseLocation()) && StringUtils.isBlank(endpoint.getLocation());
        if (StringUtils.isBlank(endpoint.getBinding()) || missingLocation) {
            throw new SamlException("Endpoint for " + authnRequest.getSchemaType()
                + " does not define a binding or location for binding " + binding);
        }
        return endpoint;
    }

    private static AssertionConsumerService determineEndpointForRequest(final RequestAbstractType authnRequest,
                                                                        final SamlRegisteredServiceMetadataAdaptor adaptor,
                                                                        final String binding,
                                                                        @Nullable final AssertionConsumerService acsFromRequest,
                                                                        final AssertionConsumerService acsFromMetadata,
                                                                        final MessageContext authenticationContext) {
        LOGGER.trace("ACS from authentication request is [{}], ACS from metadata is [{}] with binding [{}]",
            acsFromRequest, acsFromMetadata, binding);

View on GitHub (pinned to e7288fc434)