apereo/cas · error · SamlException

Endpoint for does not define a binding or location for…

Error message

Endpoint for  does not define a binding or location for binding 

What it means

In SamlIdPUtils.determineEndpointForRequest(), an Endpoint was found for the binding but it is unusable: either getBinding() is blank, or both getResponseLocation() and getLocation() are blank. CAS throws SamlException because a response cannot be delivered to an endpoint without a binding and location.

Solutions

  1. Open the SP metadata and ensure the selected <md:AssertionConsumerService> (or endpoint for that binding) has non-empty Binding and Location attributes.
  2. Regenerate/re-import the SP metadata from the vendor instead of hand-maintaining it.
  3. If using ResponseLocation-only endpoints (e.g. some Artifact endpoints), also set Location, since CAS requires at least one of the two.
  4. Validate metadata with an XML schema validator before publishing it to CAS.

Example fix

// before
<md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" index="0"/>

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

Strategy: validation

Validate before calling

// validate metadata ACS entries at load time
acsList.forEach(acs -> {
    if (acs.getLocation() == null || acs.getLocation().isBlank())
        throw new SamlException("ACS index " + acs.getIndex() + " has no Location");
    if (acs.getBinding() == null || acs.getBinding().isBlank())
        throw new SamlException("ACS index " + acs.getIndex() + " has no Binding");
});

Try / catch

try {
    endpoint = determineEndpointForRequest(authnRequest, adaptor, binding, fromReq, fromMeta, ctx);
} catch (SamlException e) {
    logger.error("Endpoint incomplete for {}: {}", adaptor.getEntityId(), e.getMessage());
}

Prevention

When it happens

Trigger: The metadata AssertionConsumerService or selected endpoint matching the binding has a Binding attribute or Location/ResponseLocation attribute missing/empty in the SP's SPSSODescriptor.

Common situations: Hand-edited or generated metadata with an ACS entry missing the Location attribute, a template that left Location blank, or metadata transformations that dropped attributes.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08). Data as JSON: /api/errors/180a99d7ebd57ee8. 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:124

                                                       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);

        if (acsFromRequest != null) {
            if (!authnRequest.isSigned() && !SAMLBindingSupport.isMessageSigned(authenticationContext)) {
                val locations = StringUtils.isNotBlank(binding)
                    ? adaptor.getAssertionConsumerServiceLocations(binding)

View on GitHub (pinned to e7288fc434)