twentyhq/twenty · error · Error
KeyInfo element is missing
Error message
KeyInfo element is missing
What it means
Thrown when a KeyDescriptor element was found inside IDPSSODescriptor but it has no XMLDSig <KeyInfo> child element. KeyInfo is the standard wrapper (under the ds/dsig namespace) holding the <X509Data>. Without it the parser cannot reach the certificate.
Source
Thrown at packages/twenty-front/src/modules/settings/security/utils/parseSAMLMetadataFromXMLFile.ts:85
const parser = new DOMParser();
const xmlDoc = parser.parseFromString(xmlString, 'application/xml');
if (xmlDoc.getElementsByTagName('parsererror').length > 0) {
throw new Error('File is not valid XML');
}
const entityDescriptor = getByPrefixAndKey(xmlDoc, 'EntityDescriptor');
if (!entityDescriptor)
throw new Error('EntityDescriptor element is missing');
const IDPSSODescriptor = getByPrefixAndKey(xmlDoc, 'IDPSSODescriptor');
if (!IDPSSODescriptor)
throw new Error('IDPSSODescriptor element is missing');
const keyDescriptors = getByPrefixAndKey(IDPSSODescriptor, 'KeyDescriptor');
if (!keyDescriptors) throw new Error('KeyDescriptor element is missing');
const keyInfo = getByPrefixAndKey(keyDescriptors, 'KeyInfo');
if (!keyInfo) throw new Error('KeyInfo element is missing');
const x509Data = getByPrefixAndKey(keyInfo, 'X509Data');
if (!x509Data) throw new Error('X509Data element is missing');
const x509Certificate = getByPrefixAndKey(
x509Data,
'X509Certificate',
)?.textContent?.trim();
if (!x509Certificate)
throw new Error('X509Certificate is missing or empty');
const singleSignOnServices = getAllByPrefixAndKey(
IDPSSODescriptor,
'SingleSignOnService',
).map((service) => ({
binding: service.getAttribute('Binding'),
location: service.getAttribute('Location'),
}));View on GitHub (pinned to 1f5dd2bbd2)
Solutions
- Inspect the KeyDescriptor in the uploaded XML and confirm a <KeyInfo> child is present.
- Ensure the KeyInfo element uses the ds/dsig (or md/ns0/ns2) prefix that the parser recognizes.
- Re-download the metadata XML directly from the IdP to avoid truncation.
Example fix
// before: <md:KeyDescriptor use="encryption"><xenc:EncryptionMethod .../></md:KeyDescriptor> (no KeyInfo) // after: <md:KeyDescriptor use="signing"><ds:KeyInfo><ds:X509Data>...</ds:X509Data></ds:KeyInfo></md:KeyDescriptor>
Defensive patterns
Strategy: validation
Validate before calling
const hasKeyInfo = (xml: string): boolean => {
const doc = new DOMParser().parseFromString(xml, 'application/xml');
return ['md', 'ns0', 'ns2', 'dsig', 'ds', ''].some((p) =>
doc.getElementsByTagName(p ? `${p}:KeyInfo` : 'KeyInfo').length > 0);
}; Type guard
const metadataHasSigningKeyInfo = (xml: string): boolean => /<[^>]*KeyDescriptor[^>]*use=["']signing["'][\s\S]*?<[^>]*KeyInfo[\s\S]*?<\/[^>]*KeyDescriptor>/.test(xml);
Try / catch
const res = parseSAMLMetadataFromXMLFile(xml);
if (!res.success) {
setFieldError('metadataFile', res.reason); // 'KeyInfo element is missing'
return;
} Prevention
- Inspect the KeyDescriptor for use="signing"; some IdPs only emit encryption KeyDescriptors.
- Confirm the ds/dsig prefix is recognized by the parser.
- Re-download metadata from the IdP to avoid truncation.
When it happens
Trigger: KeyDescriptor exists but is self-closing or empty, or only carries an encryption role with no KeyInfo. KeyInfo is present but under a namespace prefix outside the md/ns0/ns2/dsig/ds allowlist, so getByPrefixAndKey returns undefined.
Common situations: IdP metadata where only an encryption KeyDescriptor is published and the signing one is stripped. Copy-paste of metadata truncates the KeyInfo subtree. Namespace prefix mismatch on the dsig portion.
Related errors
- KeyDescriptor element is missing
- X509Data element is missing
- X509Certificate is missing or empty
- No SingleSignOnService with HTTP-Redirect or HTTP-POST bindi
- File is not valid XML
AI-assisted analysis of twentyhq/twenty@1f5dd2bbd2 (2026-08-12).
Data as JSON: /api/errors/808f7a248d092c9c.
Report an issue: GitHub.