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

  1. Obtain metadata from the IdP that includes signing KeyDescriptors with X509 certificates and re-import
  2. Manually add the IdP certificate via RelyingPartyRegistration.Builder.assertingParty(details -> details.verificationX509Credentials(c -> c.add(...))) instead of relying solely on metadata
  3. 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)
  4. 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

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

Related errors


AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10). Data as JSON: /api/errors/08170664da714563. Report an issue: GitHub.