spring-projects/spring-security · error · Saml2AuthenticationException
relying_party_registration_not_found
relying_party_registration_not_found
Error message
No relying party registration found
What it means
Saml2WebSsoAuthenticationFilter.attemptAuthentication could not find a RelyingPartyRegistration matching the incoming SAMLResponse (via the stored AuthnRequest / registrationId resolved from the request). Unless continueChainWhenNoRelyingPartyRegistrationFound is enabled, it throws Saml2AuthenticationException with code relying_party_registration_not_found. It means the SP has no registration configured for the IDP that responded.
Source
Thrown at saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/web/authentication/Saml2WebSsoAuthenticationFilter.java:138
setAuthenticationConverter(authenticationConverter);
}
@Override
protected boolean requiresAuthentication(HttpServletRequest request, HttpServletResponse response) {
return super.requiresAuthentication(request, response);
}
@Override
public @Nullable Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
throws AuthenticationException {
Authentication authentication = this.authenticationConverter.convert(request);
if (authentication == null) {
if (this.continueChainWhenNoRelyingPartyRegistrationFound) {
return null;
}
Saml2Error saml2Error = new Saml2Error(Saml2ErrorCodes.RELYING_PARTY_REGISTRATION_NOT_FOUND,
"No relying party registration found");
throw new Saml2AuthenticationException(saml2Error);
}
setDetails(request, authentication);
this.authenticationRequestRepository.removeAuthenticationRequest(request, response);
return getAuthenticationManager().authenticate(authentication);
}
/**
* Use the given {@link Saml2AuthenticationRequestRepository} to remove the saved
* authentication request. If the {@link #authenticationConverter} is of the type
* {@link Saml2AuthenticationTokenConverter}, the
* {@link Saml2AuthenticationRequestRepository} will also be set into the
* {@link #authenticationConverter}.
* @param authenticationRequestRepository the
* {@link Saml2AuthenticationRequestRepository} to use
* @since 5.6
*/
public void setAuthenticationRequestRepository(
Saml2AuthenticationRequestRepository<AbstractSaml2AuthenticationRequest> authenticationRequestRepository) {View on GitHub (pinned to 96852e8860)
Solutions
- Add or fix the RelyingPartyRegistration for the responding IDP (correct entityId/issuer metadata) in the RelyingPartyRegistrationRepository
- Confirm all nodes behind the load balancer share the same security configuration
- For IDP-initiated SSO, ensure the registration exists and matches the IdP entityID, or enable idpInitiatedLogin if supported
- Call saml2Login continuation via .saml2Login(Customizer.withDefaults()) and consider continueChainWhenNoRelyingPartyRegistrationFound if you want to pass through unhandled responses
- Verify the saved Saml2AuthenticationRequest still exists (session replication, sticky sessions)
Example fix
// before
http.saml2Login(Customizer.withDefaults()); // registration id "adfs" only, IDP sends entityID "https://adfs.example.com/adfs/services/trust"
// after: align registration with the IDP's actual entityID
http.saml2Login(saml2 -> saml2.relyingPartyRegistration(r -> r
.registrationId("adfs")
.entityId("https://adfs.example.com/adfs/services/trust")
.assertingParty(p -> p.entityId("https://adfs.example.com/adfs/services/trust")))); Defensive patterns
Strategy: try-catch
Validate before calling
String registrationId = /* resolved from request/session */;
if (registrations.findByRegistrationId(registrationId) == null) {
log.warn("No RelyingPartyRegistration for id " + registrationId);
} Try / catch
try { /* sso filter chain runs */ } catch (Saml2AuthenticationException ex) {
if (Saml2ErrorCodes.RELYING_PARTY_REGISTRATION_NOT_FOUND.equals(ex.getSaml2Error().getErrorCode())) {
log.warn("SAMLResponse from unconfigured IDP", ex);
response.sendError(HttpServletResponse.SC_BAD_REQUEST);
} else { throw ex; }
} Prevention
- Keep registrations in sync across all instances (shared config/DB)
- Verify the registration entityId matches each IDP's entityID
- Use metadata import instead of hand-written entityIds
- Enable session replication so saved AuthnRequests survive failover
When it happens
Trigger: A SAMLResponse arrives at the SSO endpoint but the resolved registrationId has no matching RelyingPartyRegistration, or no authentication request was found for this request (e.g. unsolicited response / IDP-initiated SSO without matching registration).
Common situations: Registration removed or renamed after the user started SSO; multiple IDPs and the response's issuer isn't in the config; load-balanced nodes with different saml2 registration configs; IDP-initiated SSO where the SP only supports SP-initiated; expired/cleared HttpSession losing the saved authentication request.
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
- invalid_destination
- relying_party_registration_not_found
- registration not found
- Cannot apply {configurer} to already built object
- managerPassword is required if managerDn is supplied
AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10).
Data as JSON: /api/errors/b89e13409e241604.
Report an issue: GitHub.