spring-projects/spring-security · error · Saml2Exception

registration not found

Error message

registration not found

What it means

RequestMatcherMetadataResponseResolver.responseByRegistrationId looks up a RelyingPartyRegistration by the id matched from the metadata request URL. If the RelyingPartyRegistrationRepository has no such registration, it throws Saml2Exception('registration not found') instead of returning a null/404 response.

Source

Thrown at saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/web/metadata/RequestMatcherMetadataResponseResolver.java:127

		}
		if (this.registrations instanceof IterableRelyingPartyRegistrationRepository iterable) {
			return responseByIterable(request, iterable);
		}
		if (this.registrations instanceof Iterable<?>) {
			Iterable<RelyingPartyRegistration> registrations = (Iterable<RelyingPartyRegistration>) this.registrations;
			return responseByIterable(request, registrations);
		}
		return null;
	}

	private @Nullable Saml2MetadataResponse responseByRegistrationId(HttpServletRequest request,
			@Nullable String registrationId) {
		if (registrationId == null) {
			return null;
		}
		RelyingPartyRegistration registration = this.registrations.findByRegistrationId(registrationId);
		if (registration == null) {
			throw new Saml2Exception("registration not found");
		}
		return responseByIterable(request, Collections.singleton(registration));
	}

	private Saml2MetadataResponse responseByIterable(HttpServletRequest request,
			Iterable<RelyingPartyRegistration> registrations) {
		Map<String, RelyingPartyRegistration> results = new LinkedHashMap<>();
		for (RelyingPartyRegistration registration : registrations) {
			RelyingPartyRegistrationPlaceholderResolvers.UriResolver uriResolver = RelyingPartyRegistrationPlaceholderResolvers
				.uriResolver(request, registration);
			String entityId = Objects.requireNonNull(uriResolver.resolve(registration.getEntityId()));
			results.computeIfAbsent(entityId, (e) -> {
				String ssoLocation = uriResolver.resolve(registration.getAssertionConsumerServiceLocation());
				ssoLocation = Objects.requireNonNull(ssoLocation);
				String sloLocation = uriResolver.resolve(registration.getSingleLogoutServiceLocation());
				String sloResponseLocation = uriResolver.resolve(registration.getSingleLogoutServiceResponseLocation());
				return registration.mutate()
					.entityId(entityId)

View on GitHub (pinned to 96852e8860)

Solutions

  1. Correct the registrationId in the metadata URL to exactly match one configured in your RelyingPartyRegistrationRepository.
  2. Add the missing RelyingPartyRegistration to the repository or use the no-arg/iterable resolve path so metadata is generated for all registrations.
  3. If the registration was intentionally removed, update the IdP or clients requesting that metadata URL.
  4. Wrap the metadata resolver in a handler that converts this exception to HTTP 404 for cleaner client behavior.

Example fix

// before: URL requests an unconfigured id
// GET /saml2/service-provider-metadata/idp-b (only 'idp-a' configured)
// after: add or correct
RelyingPartyRegistration idpB = RelyingPartyRegistration.withRegistrationId("idp-b")
        .entityId("https://idp.example.com/metadata")
        .singleSignOnServiceLocation("https://idp.example.com/SSO")
        .build();
Defensive patterns

Strategy: validation

Validate before calling

String registrationId = /* extracted from metadata URL */;
if (repository.findByRegistrationId(registrationId) == null) {
    throw new ResponseStatusException(HttpStatus.NOT_FOUND, "unknown registration " + registrationId);
}

Try / catch

try {
    return metadataResolver.resolve(request);
} catch (Saml2Exception ex) {
    response.sendError(HttpServletResponse.SC_NOT_FOUND);
    return null;
}

Prevention

When it happens

Trigger: A GET to the metadata endpoint (e.g. /saml2/service-provider-metadata/{registrationId}) whose registrationId path variable is not found via this.registrations.findByRegistrationId(registrationId), which returns null.

Common situations: Typo or wrong case in the metadata URL; metadata endpoint cached/bookmarked after the registration was renamed or removed; metadata published for an IdP-specific registration id that isn't configured; load balancer routing to an instance with different config.

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10). Data as JSON: /api/errors/98cec57814fa056c. Report an issue: GitHub.