{"record":{"id":"8055a7ed010e0d8c","repo":"medusajs/medusa","slug":"the-email-domain-is-not-allowed-to-authenticate-wi","errorCode":null,"errorMessage":"The email domain is not allowed to authenticate with this provider","messagePattern":"The email domain is not allowed to authenticate with this provider","errorType":"exception","errorClass":"MedusaError","httpStatus":401,"severity":"error","filePath":"packages/modules/providers/auth-oidc/src/engine/engine.ts","lineNumber":247,"sourceCode":"    const requireVerifiedEmail = this.options_.require_verified_email ?? true\n    if (requireVerifiedEmail && claims.email_verified !== true) {\n      throw new MedusaError(\n        MedusaError.Types.INVALID_DATA,\n        \"The identity provider did not confirm a verified email address\"\n      )\n    }\n\n    if (this.options_.allowed_email_domains?.length) {\n      const allowedDomains = this.options_.allowed_email_domains.map((domain) =>\n        domain.toLowerCase()\n      )\n      const domain =\n        typeof email === \"string\"\n          ? email.split(\"@\")[1]?.toLowerCase()\n          : undefined\n\n      if (!domain || !allowedDomains.includes(domain)) {\n        throw new MedusaError(\n          MedusaError.Types.UNAUTHORIZED,\n          \"The email domain is not allowed to authenticate with this provider\"\n        )\n      }\n    }\n\n    const userMetadata: Record<string, unknown> = {}\n    for (const [field, claimName] of Object.entries(mappings)) {\n      if (field === \"entity_id\" || !claimName) {\n        continue\n      }\n      if (isDefined(claims[claimName])) {\n        userMetadata[field] = claims[claimName]\n      }\n    }\n\n    return {\n      entityId: String(entityIdValue),","sourceCodeStart":229,"sourceCodeEnd":265,"githubUrl":"https://github.com/medusajs/medusa/blob/5e06e544a296b9033f20f71f11c559f81a0e5739/packages/modules/providers/auth-oidc/src/engine/engine.ts#L229-L265","documentation":"When allowed_email_domains is configured, the engine extracts the domain from the mapped email claim and checks membership in the allow-list. An email with no parseable domain or a domain not in the list is rejected with UNAUTHORIZED.","triggerScenarios":"allowed_email_domains: [\"acme.com\"] is set and a user authenticates with user@gmail.com, or the mapped email claim is not a string so no domain can be extracted.","commonSituations":"Restricting a corporate SSO to company domains and users try personal addresses; the allow-list entries have different casing or subdomains (sub.acme.com vs acme.com — only exact lowercase match passes); test users provisioned with an email outside the list.","solutions":["Add the user's domain (lowercase, exact) to allowed_email_domains in the provider options.","For subdomain support, list each subdomain explicitly — the check is an exact match, not suffix-based.","If the restriction is unintended, remove the allowed_email_domains option entirely."],"exampleFix":"// before\noptions: { ..., allowed_email_domains: [\"acme.com\"] }\n// after\noptions: { ..., allowed_email_domains: [\"acme.com\", \"sub.acme.com\"] }","handlingStrategy":"validation","validationCode":"const domain = email?.split(\"@\")[1]?.toLowerCase()\nif (allowedDomains.length && !allowedDomains.includes(domain)) {\n  return res.status(403).json({ error: \"email_domain_not_allowed\" })\n}","typeGuard":"const isAllowedDomain = (email: string | undefined, allowed: string[]): boolean =>\n  !!email && allowed.includes(email.split(\"@\")[1]?.toLowerCase() ?? \"\")","tryCatchPattern":"try { engine.mapClaims(claims) } catch (e) { if (e instanceof MedusaError && e.type === MedusaError.Types.UNAUTHORIZED && /domain is not allowed/.test(e.message)) { res.status(403).json({ error: \"email_domain_not_allowed\" }); return } throw e }","preventionTips":["List domains lowercase and include each subdomain explicitly (exact match only).","Surface a clear 'use your company account' message in the UI for this case.","Review the allow-list whenever the company domain changes."],"tags":["oidc","email-domain","allow-list","authorization"],"backgroundTag":"email-domain-restriction","analyzedSha":"5e06e544a296b9033f20f71f11c559f81a0e5739","analyzedAt":"2026-08-27T07:24:39.599Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}