decolua/9router · error
IdP X.509 Certificate (samlCert) is missing or not configure
Error message
IdP X.509 Certificate (samlCert) is missing or not configured
What it means
validateSamlResponse refuses to process a SAML POST assertion until an IdP X.509 certificate has been configured in settings (settings.samlCert). The certificate is required to construct the @node-saml instance and to verify the digital signature of the SAMLResponse; without it, assertions cannot be trusted. The check runs first, before any parsing or validation of the response body.
Source
Thrown at src/lib/auth/saml.js:135
const match = xml.match(/ID="([^"]+)"/);
const requestId = match ? match[1] : "";
const authorizeUrl = await samlInstance._requestToUrlAsync(xml, null, "authorize", {});
return { authorizeUrl, requestId };
}
/**
* Validates SAML POST response from IdP ACS callback and returns user profile.
* @param {Request} request
* @param {object} body - Parsed form body or object containing SAMLResponse
* @param {string} expectedRequestId - Request ID stored in saml_state cookie
* @param {object} settings
* @returns {Promise<object>}
*/
export async function validateSamlResponse(request, body, expectedRequestId, settings) {
if (!settings?.samlCert) {
throw new Error("IdP X.509 Certificate (samlCert) is missing or not configured");
}
const origin = getSamlBaseUrl(request, settings);
const samlInstance = createSamlInstance(settings, origin);
const container = typeof body === "object" && body !== null ? body : { SAMLResponse: body };
const rawSamlResponse = container.SAMLResponse;
if (!rawSamlResponse) {
throw new Error("Missing SAMLResponse parameter in assertion POST body");
}
// Parse response XML to inspect InResponseTo for replay protection
if (expectedRequestId) {
const xml = Buffer.from(rawSamlResponse, "base64").toString("utf8");
const match = xml.match(/InResponseTo=["']([^"']+)["']/i);
const inResponseTo = match ? match[1] : null;
View on GitHub (pinned to 90b52e06ff)
Solutions
- Open the dashboard SAML settings and paste the IdP's X.509 certificate (PEM, base64 body) into the samlCert field, then save.
- Export the certificate from your IdP (e.g. Okta/Entra 'Signing certificate', ADFS token-signing cert) and verify it matches the IdP currently issuing assertions.
- If settings come from an import/sync, re-run the import and confirm samlCert is present in the payload before retrying the login.
- Log/inspect the settings object passed to validateSamlResponse to confirm the key is named exactly samlCert and is non-empty.
Example fix
// before
await validateSamlResponse(req, req.body, stateId, settings); // settings.samlCert === undefined
// after
if (!settings?.samlCert) throw new Error('Configure IdP X.509 certificate (samlCert) in settings first');
await validateSamlResponse(req, req.body, stateId, settings); Defensive patterns
Strategy: validation
Validate before calling
function isSamlConfigReady(settings) {
return typeof settings?.samlCert === 'string' && settings.samlCert.trim().length > 0;
}
// call: if (!isSamlConfigReady(settings)) redirect to SSO setup instead of invoking validateSamlResponse Type guard
function hasSamlCert(s) {
return !!s && typeof s === 'object' && typeof s.samlCert === 'string' && s.samlCert.trim() !== '';
} Try / catch
try {
const profile = await validateSamlResponse(req, body, stateId, settings);
} catch (err) {
if (String(err.message).includes('samlCert')) {
return res.status(503).json({ error: 'SAML not configured', hint: 'Set the IdP X.509 certificate in settings' });
}
throw err;
} Prevention
- Validate SAML settings (cert present, well-formed PEM) at save time in the admin UI, not only at login time.
- Add a startup/health check that warns when SAML is enabled but samlCert is empty.
- After IdP certificate rotation, update samlCert and re-test login; keep the old cert temporarily if the IdP supports dual signing certs.
- Store settings via a single schema-validated path so imports/syncs cannot silently drop the samlCert key.
When it happens
Trigger: Calling validateSamlResponse(request, body, expectedRequestId, settings) where settings is null/undefined, settings.samlCert is undefined, an empty string, or whitespace (falsy).
Common situations: Admin enabled SAML login but never pasted the IdP's certificate into settings; the certificate field was saved to the wrong settings key; settings were imported/migrated and samlCert was dropped; a fresh environment was provisioned without completing IdP metadata setup; the certificate was rotated and the new cert removed rather than replacing the old one.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- Missing SAMLResponse parameter in assertion POST body
- InResponseTo mismatch: expected ${expectedRequestId}, receiv
- No active credentials for provider: ${provider}
- Vertex partner models require a project_id. Add it in provid
- Vertex: failed to mint access token from Service Account JSO
AI-assisted analysis of decolua/9router@90b52e06ff (2026-08-30).
Data as JSON: /api/errors/66d8743ee3188a82.
Report an issue: GitHub.