apereo/cas · warning

Unable to locate acs url in for entity

Error message

Unable to locate acs url in for entity [{}] and binding [{}] with index [{}]

What it means

SamlIdPUtils.getAssertionConsumerServiceFromRequest() resolves the ACS URL from a SAML request using either an explicit ACS URL or an ACS index for the given binding. When acsIndex is provided but the service provider metadata adapter has no AssertionConsumerService for that binding/index combination, it logs this warning and yields null, meaning no ACS endpoint could be determined. Callers typically reject the request or fall back to the default ACS.

Solutions

  1. Compare the acsIndex in the request against the ACS entries in the SP's entity descriptor in the IdP metadata
  2. Refresh/reload the SP metadata so the declared indexes match what the SP sends
  3. Have the SP send an explicit AssertionConsumerServiceURL instead of relying on the index
  4. Fix the SP configuration so the index matches a valid binding (e.g. POST vs Redirect) in its metadata

Example fix

// before: SP sends index 7 that IdP metadata lacks
AssertionConsumerServiceIndex="7"
// after: send explicit URL or use a valid index
AssertionConsumerServiceURL="https://sp.example.com/acs"
Defensive patterns

Strategy: validation

Validate before calling

// validate the requested index against SP metadata
val valid = adapter.getAssertionConsumerServiceFor(binding, acsIndex);
if (valid.isEmpty()) log.error('SP sent unknown ACS index ' + acsIndex);

Type guard

function hasAcs(url) { return typeof url === 'string' && url.length > 0; }

Try / catch

val acs = SamlIdPUtils.getAssertionConsumerServiceFromRequest(...);
if (acs == null) { /* reject request or fall back to default ACS */ }

Prevention

When it happens

Trigger: A SAML AuthnRequest carries an AssertionConsumerServiceIndex (or the caller passes acsIndex) that does not match any ACS entry declared for that binding in the SP metadata; the metadata for the entity is stale or missing that index.

Common situations: SP sends an index from an old metadata version after the IdP reloaded newer/older metadata; hand-written requests guessing an index; metadata not refreshed after the SP changed its ACS endpoints; binding mismatch between requested protocol and metadata entries.

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/1c4930daa37a0a8b. 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:290

        }
        return Optional.empty();
    }

    private static @Nullable AssertionConsumerService getAssertionConsumerServiceFromRequest(final RequestAbstractType request,
                                                                                             final String binding,
                                                                                             final SamlRegisteredServiceMetadataAdaptor adapter) {
        if (request instanceof final AuthnRequest authnRequest) {
            var acsUrl = authnRequest.getAssertionConsumerServiceURL();
            val acsIndex = authnRequest.getAssertionConsumerServiceIndex();
            if (StringUtils.isBlank(acsUrl) && acsIndex == null) {
                LOGGER.debug("No assertion consumer service url or index is supplied in the authentication request");
                return null;
            }
            if (StringUtils.isBlank(acsUrl) && acsIndex != null) {
                LOGGER.debug("Locating assertion consumer service url for binding [{}] and index [{}]", acsUrl, acsIndex);
                acsUrl = adapter.getAssertionConsumerServiceFor(binding, acsIndex)
                    .orElseGet(() -> {
                        LOGGER.warn("Unable to locate acs url in for entity [{}] and binding [{}] with index [{}]",
                            adapter.getEntityId(), binding, acsIndex);
                        return null;
                    });
            }

            if (StringUtils.isNotBlank(acsUrl)) {
                LOGGER.debug("Fetched assertion consumer service url [{}] with binding [{}] from authentication request", acsUrl, binding);
                val builder = new AssertionConsumerServiceBuilder();
                val endpoint = builder.buildObject(AssertionConsumerService.DEFAULT_ELEMENT_NAME);
                endpoint.setBinding(binding);
                endpoint.setResponseLocation(acsUrl);
                endpoint.setLocation(acsUrl);
                endpoint.setIndex(acsIndex);
                return endpoint;
            }
        }
        return null;
    }

View on GitHub (pinned to e7288fc434)