spring-projects/spring-security · error · Saml2Exception
Metadata response is missing verification certificates, nece
Error message
Metadata response is missing verification certificates, necessary for verifying SAML assertions
What it means
Spring Security SAML2 throws this Saml2Exception when parsing an asserting party's (IdP) metadata that contains no verification (validation) certificates. Verification X509 certificates are required to validate signatures on SAML assertions and responses from that IdP; without them the framework cannot trust any assertion it receives, so it refuses to build the RelyingPartyRegistration.
Source
Thrown at saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/registration/OpenSamlAssertingPartyDetails.java:113
verification.add(Saml2X509Credential.verification(certificate));
}
}
if (UsageType.ENCRYPTION.equals(keyDescriptor.getUse())) {
List<X509Certificate> certificates = certificates(keyDescriptor);
for (X509Certificate certificate : certificates) {
encryption.add(Saml2X509Credential.encryption(certificate));
}
}
if (UsageType.UNSPECIFIED.equals(keyDescriptor.getUse())) {
List<X509Certificate> certificates = certificates(keyDescriptor);
for (X509Certificate certificate : certificates) {
verification.add(Saml2X509Credential.verification(certificate));
encryption.add(Saml2X509Credential.encryption(certificate));
}
}
}
if (verification.isEmpty()) {
throw new Saml2Exception(
"Metadata response is missing verification certificates, necessary for verifying SAML assertions");
}
String entityId = entity.getEntityID();
Assert.notNull(entityId, "EntityDescriptor#EntityID cannot be null");
OpenSamlAssertingPartyDetails.Builder builder = new OpenSamlAssertingPartyDetails.Builder(entity)
.entityId(entityId)
.wantAuthnRequestsSigned(Boolean.TRUE.equals(idpssoDescriptor.getWantAuthnRequestsSigned()))
.verificationX509Credentials((c) -> c.addAll(verification))
.encryptionX509Credentials((c) -> c.addAll(encryption));
List<SigningMethod> signingMethods = signingMethods(idpssoDescriptor);
for (SigningMethod method : signingMethods) {
Assert.notNull(method.getAlgorithm(), "EntityDescriptor declares a SigningMethod with no value");
builder.signingAlgorithms((algorithms) -> algorithms.add(method.getAlgorithm()));
}
if (idpssoDescriptor.getSingleSignOnServices().isEmpty()) {
throw new Saml2Exception(
"Metadata response is missing a SingleSignOnService, necessary for sending AuthnRequests");View on GitHub (pinned to 96852e8860)
Solutions
- Obtain metadata from the IdP that includes signing KeyDescriptors with X509 certificates and re-import
- Manually add the IdP certificate via RelyingPartyRegistration.Builder.assertingParty(details -> details.verificationX509Credentials(c -> c.add(...))) instead of relying solely on metadata
- If the IdP really signs nothing (unsigned responses), configure the registration to not require signed assertions and secure the exchange another way (e.g. require POST binding over TLS with a trusted endpoint)
- Verify you fetched the metadata of the actual IdP entity, not an aggregate missing per-entity KeyDescriptors
Example fix
// before (metadata without signing keys -> error)
RelyingPartyRegistration r = RelyingPartyRegistrations.fromMetadataLocation("https://idp/meta").build();
// after: supply verification cert explicitly when metadata lacks it
RelyingPartyRegistration r = RelyingPartyRegistration.withAssertingPartyMetadata(party -> party
.entityId("https://idp.example.com/sso")
.singleSignOnServiceLocation("https://idp.example.com/sso")
.verificationX509Credentials(c -> c.add(new Saml2X509Credential(certificate, Saml2X509CredentialType.VERIFICATION))))
.registrationId("idp")
.build(); Defensive patterns
Strategy: validation
Validate before calling
// Pre-check metadata contains signing certs before import
Document doc = parseXml(metadataBytes);
NodeList kds = doc.getElementsByTagNameNS("urn:oasis:names:tc:SAML:2.0:metadata", "KeyDescriptor");
boolean hasSigningCert = false;
for (int i = 0; i < kds.getLength(); i++) {
String use = ((Element) kds.item(i)).getAttribute("use");
if (use.isEmpty() || use.equals("signing")) { hasSigningCert = true; break; }
}
if (!hasSigningCert) throw new IllegalArgumentException("Metadata has no signing certificates"); Try / catch
try {
return RelyingPartyRegistrations.fromMetadataLocation(location).build();
} catch (Saml2Exception ex) {
logger.error("Metadata missing verification certificates; supply manually", ex);
return fallbackRegistrationWithManualCert();
} Prevention
- Always validate downloaded metadata contains KeyDescriptor use=signing with X509Certificate before import
- Keep IdP signing certificates in your application config as a fallback to metadata
- Test metadata import in CI with the real IdP metadata artifact
When it happens
Trigger: Calling RelyingPartyRegistrations.fromMetadata(…)/fromMetadataLocation(…), or OpenSamlAssertingPartyDetails.withEntityDescriptor(...), on metadata whose IDPSSODescriptor has no KeyDescriptor with signing-use certificates (verification list ends up empty).
Common situations: IdP metadata file omits <md:KeyDescriptor use="signing"> or any KeyDescriptor at all; developer hand-wrote minimal metadata; metadata endpoint returned a stub/health document; key rollover temporarily removed certs from published metadata.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- Metadata response is missing a SingleSignOnService, necessar
- Unsupported element type:
- Metadata response is missing the necessary IDPSSODescriptor
- registration not found
- invalid_destination
AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10).
Data as JSON: /api/errors/08170664da714563.
Report an issue: GitHub.