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
- Correct the registrationId in the metadata URL to exactly match one configured in your RelyingPartyRegistrationRepository.
- Add the missing RelyingPartyRegistration to the repository or use the no-arg/iterable resolve path so metadata is generated for all registrations.
- If the registration was intentionally removed, update the IdP or clients requesting that metadata URL.
- 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
- Generate metadata URLs from the configured registrationIds, never hardcode them.
- Add a startup check that each expected registration resolves from the repository.
- Purge cached/bookmarked metadata URLs after renaming registrations.
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
- invalid_destination
- Metadata response is missing verification certificates, nece
- Metadata response is missing a SingleSignOnService, necessar
- Unsupported element type:
- Metadata response is missing the necessary IDPSSODescriptor
AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10).
Data as JSON: /api/errors/98cec57814fa056c.
Report an issue: GitHub.