medusajs/medusa · error · MedusaError
The identity provider's ID token is missing the '${entityIdC
Error message
The identity provider's ID token is missing the '${entityIdClaim}' claim used to identify the user What it means
mapClaims extracts the user identifier from a configurable claim (mappings.entity_id, defaulting typically to 'sub'). If that claim is absent, null, or empty string in the ID token, the engine cannot identify the user and throws INVALID_DATA naming the missing claim.
Source
Thrown at packages/modules/providers/auth-oidc/src/engine/engine.ts:220
*
* `entity_id` defaults to the `sub` claim (never the email, which is mutable
* and reassignable).
*/
mapClaims(claims: Record<string, unknown>): OidcMappedClaims {
const mappings: OidcClaimMappings = {
...DEFAULT_CLAIM_MAPPINGS,
...this.options_.claim_mappings,
}
const entityIdClaim = mappings.entity_id ?? "sub"
const entityIdValue = claims[entityIdClaim]
if (
entityIdValue === undefined ||
entityIdValue === null ||
entityIdValue === ""
) {
throw new MedusaError(
MedusaError.Types.INVALID_DATA,
`The identity provider's ID token is missing the '${entityIdClaim}' claim used to identify the user`
)
}
const emailClaim = mappings.email ?? "email"
const email = claims[emailClaim]
const requireVerifiedEmail = this.options_.require_verified_email ?? true
if (requireVerifiedEmail && claims.email_verified !== true) {
throw new MedusaError(
MedusaError.Types.INVALID_DATA,
"The identity provider did not confirm a verified email address"
)
}
if (this.options_.allowed_email_domains?.length) {
const allowedDomains = this.options_.allowed_email_domains.map((domain) =>View on GitHub (pinned to 5e06e544a2)
Solutions
- Decode the ID token (e.g. jwt.io or JSON.parse(Buffer.from(token.split('.')[1], 'base64'))) and check which claims are actually present.
- Either set mappings.entity_id to a claim that exists (commonly 'sub' or 'email'), or configure the IdP to include the desired claim in the ID token.
- Request the scopes (e.g. 'email', 'profile') that make the IdP emit the claim.
Example fix
// before
options: { ..., mappings: { entity_id: "preferred_username" } }
// after
options: { ..., mappings: { entity_id: "sub" } } Defensive patterns
Strategy: validation
Validate before calling
function decodeJwtClaims(idToken: string): Record<string, unknown> {
const payload = idToken.split(".")[1]
return JSON.parse(Buffer.from(payload, "base64url").toString("utf8"))
}
const claims = decodeJwtClaims(idToken)
if (claims[mappings.entity_id ?? "sub"] == null) throw new Error("entity_id claim missing in ID token") Type guard
const hasEntityIdClaim = (claims: Record<string, unknown>, claim: string): boolean => claims[claim] !== undefined && claims[claim] !== null && claims[claim] !== ""
Try / catch
try { engine.mapClaims(claims) } catch (e) { if (e instanceof MedusaError && /missing the '.*' claim/.test(e.message)) { /* adjust mappings or IdP claim config */ } throw e } Prevention
- Map entity_id to 'sub' unless you have verified the custom claim appears in the ID token.
- Decode a sample ID token when onboarding a new IdP.
- Request scopes that unlock the claims you map (email, profile).
When it happens
Trigger: mappings.entity_id is set to a claim the IdP does not emit (e.g. 'preferred_username' on a provider that doesn't include it in the ID token); the claim only appears in the userinfo endpoint, not the ID token; scopes needed to include the claim were not requested so the claim is empty.
Common situations: Copied claim mappings from a different IdP (Azure AD vs Keycloak vs Google emit different claims); custom claim configured in Keycloak but not added to the ID token mapper; requested scopes don't cover the claim (e.g. email claim without 'email' scope).
Related errors
- id_token is missing 'sub' claim
- The identity provider did not return an ID token; ensure the
- The identity provider did not confirm a verified email addre
- Claim with id: ${req.params.id} was not found
- id_token is missing 'sub' claim
AI-assisted analysis of medusajs/medusa@5e06e544a2 (2026-08-27).
Data as JSON: /api/errors/32939e0fe6052623.
Report an issue: GitHub.