spring-projects/spring-security · error · Saml2AuthenticationException

relying_party_registration_not_found

relying_party_registration_not_found

Error message

registration not found

What it means

BaseOpenSamlLogoutRequestValidatorParametersResolver.logoutRequestById looked up a RelyingPartyRegistration by the registrationId in the logout request (e.g. from the request parameter or path) and got null, so it throws Saml2AuthenticationException with code relying_party_registration_not_found and message 'registration not found'. Called from resolve when the registration id is supplied explicitly.

Source

Thrown at saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/web/authentication/logout/BaseOpenSamlLogoutRequestValidatorParametersResolver.java:157

			return registrationId;
		}
		if (authentication == null) {
			return null;
		}
		if (authentication instanceof Saml2AssertionAuthentication saml2) {
			return saml2.getRelyingPartyRegistrationId();
		}
		if (authentication.getPrincipal() instanceof Saml2AuthenticatedPrincipal saml2) {
			return saml2.getRelyingPartyRegistrationId();
		}
		return null;
	}

	private @Nullable Saml2LogoutRequestValidatorParameters logoutRequestById(HttpServletRequest request,
			@Nullable Authentication authentication, String registrationId) {
		RelyingPartyRegistration registration = this.registrations.findByRegistrationId(registrationId);
		if (registration == null) {
			throw new Saml2AuthenticationException(
					Saml2Error.relyingPartyRegistrationNotFound("registration not found"));
		}
		return logoutRequestByRegistration(request, registration, authentication);
	}

	private @Nullable Saml2LogoutRequestValidatorParameters logoutRequestByEntityId(HttpServletRequest request,
			@Nullable Authentication authentication) {
		String serialized = request.getParameter(Saml2ParameterNames.SAML_REQUEST);
		LogoutRequest logoutRequest = this.saml.deserialize(
				Saml2Utils.withEncoded(serialized).inflate(HttpMethod.GET.matches(request.getMethod())).decode());
		Issuer issuer = logoutRequest.getIssuer();
		Assert.notNull(issuer, "LogoutRequest#Issuer cannot be null");
		RelyingPartyRegistration registration = this.registrations.findUniqueByAssertingPartyEntityId(getValue(issuer));
		return logoutRequestByRegistration(request, registration, authentication);
	}

	private @Nullable Saml2LogoutRequestValidatorParameters logoutRequestByRegistration(HttpServletRequest request,
			@Nullable RelyingPartyRegistration registration, @Nullable Authentication authentication) {

View on GitHub (pinned to 96852e8860)

Solutions

  1. Ensure the registrationId used in the logout request matches one registered in the RelyingPartyRegistrationRepository
  2. Fix the URLs/templates that generate logout links (e.g. /logout/saml2/sso?registrationId=...)
  3. Synchronize saml2 RelyingPartyRegistration configuration across all application instances
  4. Log available registration ids at startup and compare against incoming ids

Example fix

// before (template with wrong id)
<a th:href="@{/logout/saml2/sso?registrationId=idp1}">Logout</a>
// after: derive the id from the actual registration
<a th:href="@{/logout/saml2/sso?registrationId=${saml2RegistrationId}}">Logout</a>
Defensive patterns

Strategy: try-catch

Validate before calling

if (registrations.findByRegistrationId(registrationId) == null) {
    throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Unknown registrationId " + registrationId);
}

Try / catch

try { /* resolve/logout flow */ } catch (Saml2AuthenticationException ex) {
    if ("relying_party_registration_not_found".equals(ex.getSaml2Error().getErrorCode())) {
        log.warn("Logout for unknown registration", ex);
        response.sendError(HttpServletResponse.SC_BAD_REQUEST);
    } else { throw ex; }
}

Prevention

When it happens

Trigger: A SLO request/response arrives (or resolve() is called) with a registrationId that has no RelyingPartyRegistration in the configured RelyingPartyRegistrationRepository.

Common situations: Logout link built with a stale/typo'd registrationId; registration renamed after users have existing sessions; different config across cluster nodes; metadata-driven registrations not loaded at logout time.

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 spring-projects/spring-security@96852e8860 (2026-09-10). Data as JSON: /api/errors/1df7c20fedaed01b. Report an issue: GitHub.