spring-projects/spring-security · error · Saml2Exception
registration not found
Error message
registration not found
What it means
Saml2MetadataFilter resolves the RelyingPartyRegistration for the {registrationId} path variable extracted from the request URI. When the underlying RelyingPartyRegistrationRepository has no registration with that id, resolve returns null and the filter throws this Saml2Exception instead of serving metadata.
Source
Thrown at saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/web/Saml2MetadataFilter.java:172
private String metadataFilename = DEFAULT_METADATA_FILE_NAME;
Saml2MetadataResponseResolverAdapter(RelyingPartyRegistrationResolver registrations,
Saml2MetadataResolver metadataResolver) {
this.registrations = registrations;
this.metadataResolver = metadataResolver;
}
@Override
public @Nullable Saml2MetadataResponse resolve(HttpServletRequest request) {
RequestMatcher.MatchResult matcher = this.requestMatcher.matcher(request);
if (!matcher.isMatch()) {
return null;
}
String registrationId = matcher.getVariables().get("registrationId");
RelyingPartyRegistration relyingPartyRegistration = this.registrations.resolve(request, registrationId);
if (relyingPartyRegistration == null) {
throw new Saml2Exception("registration not found");
}
registrationId = relyingPartyRegistration.getRegistrationId();
String metadata = this.metadataResolver.resolve(relyingPartyRegistration);
String fileName = this.metadataFilename.replace("{registrationId}", registrationId);
return new Saml2MetadataResponse(metadata, fileName);
}
void setRequestMatcher(RequestMatcher requestMatcher) {
Assert.notNull(requestMatcher, "requestMatcher cannot be null");
this.requestMatcher = requestMatcher;
}
void setMetadataFilename(String metadataFilename) {
Assert.hasText(metadataFilename, "metadataFilename cannot be empty");
Assert.isTrue(metadataFilename.contains("{registrationId}"),
"metadataFilename must contain a {registrationId} match variable");
this.metadataFilename = metadataFilename;
}View on GitHub (pinned to 96852e8860)
Solutions
- Fix the registrationId in the request URL to match exactly an id registered in RelyingPartyRegistrationRepository (check application.yml spring.security.saml2.relyingparty.registration.* keys).
- Verify the RelyingPartyRegistrationRepository bean actually contains the registration (log repository size or enumerate registrations).
- Confirm the request is reaching the right application/environment where the registration is configured.
- If dynamic resolution is expected, implement a custom RelyingPartyRegistrationResolver that creates registrations on demand instead of relying on a static repository.
- Catch Saml2Exception in a filter/error handler and return HTTP 404 rather than a 500 for unknown registration ids.
Example fix
// before (application.yml)
spring.security.saml2.relyingparty.registration:
idp-prod:
assertingparty.metadata-uri: https://idp.example.com/metadata
// request: GET /saml2/metadata/prod-idp -> Saml2Exception
// after
// request with matching id:
// GET /saml2/metadata/idp-prod -> metadata XML returned Defensive patterns
Strategy: try-catch
Validate before calling
String regId = matcher.getVariables().get("registrationId");
RelyingPartyRegistration r = registrations.resolve(request, regId);
if (r == null) { response.sendError(404); return; } Type guard
boolean isKnownRegistration(String id) {
try { return relyingPartyRegistrations.findByRegistrationId(id) != null; }
catch (Exception e) { return false; }
} Try / catch
try {
return metadataFilterChain.doFilter(request, response);
} catch (Saml2Exception ex) {
if (String.valueOf(ex.getMessage()).contains("registration not found")) {
response.sendError(HttpServletResponse.SC_NOT_FOUND);
} else { throw ex; }
} Prevention
- Keep registrationIds stable and share them with the IdP/partners as the exact metadata URL
- Add an integration test hitting /saml2/metadata/{id} for every configured registration
- Monitor 404s on the metadata endpoint to catch renamed registrations
When it happens
Trigger: An HTTP GET hits the metadata endpoint (/saml2/metadata/{registrationId} or /saml2/metadata/{registrationId}/metadata) with a registrationId that is not present in the configured RelyingPartyRegistrationRepository, or one whose repository lookup returns null.
Common situations: Typo or case mismatch in the registrationId in the URL; the registration was renamed or removed from application.yml / RelyingPartyRegistrationRepository bean; the app serves multiple tenants and the request uses an id registered in a different environment (dev vs prod); the repository is a CachingIterableRelyingPartyRegistrationRepository that hasn't loaded metadata for that id yet.
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
- Metadata response is missing verification certificates, nece
- Metadata response is missing a SingleSignOnService, necessar
- Unsupported element type:
- Metadata response is missing the necessary IDPSSODescriptor
- invalid_destination
AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10).
Data as JSON: /api/errors/6318e00113bf8d5c.
Report an issue: GitHub.