{"record":{"id":"f52e3f98aea72a13","repo":"spring-projects/spring-security","slug":"metadata-response-is-missing-the-necessary-idpssod-f52e3f","errorCode":null,"errorMessage":"Metadata response is missing the necessary IDPSSODescriptor element","messagePattern":"Metadata response is missing the necessary IDPSSODescriptor element","errorType":"exception","errorClass":"Saml2Exception","httpStatus":null,"severity":"error","filePath":"saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/registration/RelyingPartyRegistrations.java","lineNumber":228,"sourceCode":"\t * for signing AuthnRequests.\n\t * @param source the {@link InputStream} source containing the asserting party\n\t * metadata\n\t * @return the {@link Collection} of {@link RelyingPartyRegistration.Builder}s for\n\t * further configuration\n\t * @since 5.7\n\t */\n\tpublic static Collection<RelyingPartyRegistration.Builder> collectionFromMetadata(InputStream source) {\n\t\tCollection<RelyingPartyRegistration.Builder> builders = new ArrayList<>();\n\t\tfor (EntityDescriptor descriptor : OpenSamlMetadataUtils.descriptors(source)) {\n\t\t\tif (descriptor.getIDPSSODescriptor(SAMLConstants.SAML20P_NS) != null) {\n\t\t\t\tOpenSamlAssertingPartyDetails assertingParty = OpenSamlAssertingPartyDetails\n\t\t\t\t\t.withEntityDescriptor(descriptor)\n\t\t\t\t\t.build();\n\t\t\t\tbuilders.add(RelyingPartyRegistration.withAssertingPartyMetadata(assertingParty));\n\t\t\t}\n\t\t}\n\t\tif (builders.isEmpty()) {\n\t\t\tthrow new Saml2Exception(\"Metadata response is missing the necessary IDPSSODescriptor element\");\n\t\t}\n\t\treturn builders;\n\t}\n\n}\n","sourceCodeStart":210,"sourceCodeEnd":234,"githubUrl":"https://github.com/spring-projects/spring-security/blob/96852e8860138a482cb13d1479573f24ff6443c6/saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/registration/RelyingPartyRegistrations.java#L210-L234","documentation":"collectionFromMetadata parses the metadata and builds builders only from EntityDescriptors that contain an IDPSSODescriptor. If the document yielded no usable builders (no IdP role descriptors found, or only SP descriptors), Spring Security throws this Saml2Exception because no asserting party can be derived.","triggerScenarios":"Calling RelyingPartyRegistrations.collectionFromMetadata/collectionFromMetadataLocation on metadata whose EntityDescriptors lack IDPSSODescriptor role elements — e.g. SP-only aggregates, or EntitiesDescriptor entries that are organization/affiliate descriptors.","commonSituations":"Pointing at a federation aggregate and filtering entityIDs, but the target entities are SPs not IdPs; metadata version/role mismatch (SSO descriptor under a different namespace or protocol version, e.g. SAML 1.x only); empty EntitiesDescriptor returned by the server for an unauthorized scope.","solutions":["Verify the metadata contains <md:IDPSSODescriptor protocolSupportEnumeration=\"urn:oasis:names:tc:SAML:2.0:protocol\"> elements for the entities you expect","Use the correct aggregate or per-entity IdP metadata URL that includes IdP role descriptors","Check that server-side scoping/filters aren't returning empty EntitiesDescriptor content for your request","Fall back to per-IdP metadata URLs (fromMetadataLocation) instead of an aggregate that lacks IdP descriptors"],"exampleFix":"// before: aggregate contains only SPs\ncollectionFromMetadataLocation(\"https://federation.example.org/sp-aggregate\")\n// after: IdP aggregate or explicit entity\ncollectionFromLocation(\"https://federation.example.org/idp-aggregate\")\n// or: fromMetadataLocation(\"https://idp.example.com/saml/metadata\")","handlingStrategy":"validation","validationCode":"Document doc = parseXml(metadataBytes);\nNodeList idp = doc.getElementsByTagNameNS(\"urn:oasis:names:tc:SAML:2.0:metadata\", \"IDPSSODescriptor\");\nif (idp.getLength() == 0) throw new IllegalArgumentException(\"Metadata contains no IDPSSODescriptor\");","typeGuard":null,"tryCatchPattern":"try {\n    return RelyingPartyRegistrations.collectionFromMetadataLocation(location);\n} catch (Saml2Exception ex) {\n    if (ex.getMessage() != null && ex.getMessage().contains(\"IDPSSODescriptor\")) {\n        throw new IllegalStateException(\"Aggregate has no IdP descriptors — use IdP-specific metadata\", ex);\n    }\n    throw ex;\n}","preventionTips":["Confirm the aggregate/entities you import include SAML 2.0 IDPSSODescriptor elements","Don't use SP aggregates as asserting-party metadata","Prefer explicit per-IdP metadata URLs when unsure what an aggregate contains"],"tags":["saml2","metadata","missing-role-descriptor","spring-security"],"backgroundTag":"unexpected-response-shape","analyzedSha":"96852e8860138a482cb13d1479573f24ff6443c6","analyzedAt":"2026-09-10T23:25:23.477Z","contentChangedAt":"2026-09-10T23:25:23.477Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}