medusajs/medusa · error · MedusaError

UNAUTHORIZED

UNAUTHORIZED

Error message

Only ${authProvider} identities can create a user account for this authentication context

What it means

Thrown when the auth identity resolved from the token does not have exactly one provider identity, or that provider identity's provider does not match the :auth_provider in the URL. The route only allows creating a user through the same provider that authenticated the request. Maps to HTTP 401 (UNAUTHORIZED).

Source

Thrown at packages/medusa/src/api/auth/[auth_provider]/user/route.ts:52

      "Email is required to create a user account."
    )
  }

  // Check that the auth identity was created by the provider named in the route.
  const providerIdentities = await query
    .graph({
      entity: "auth_identity",
      fields: ["id", "provider_identities.provider"],
      filters: {
        id: req.auth_context.auth_identity_id,
      },
    })
    .then((result) => result.data[0]?.provider_identities)
  if (
    providerIdentities?.length !== 1 ||
    providerIdentities[0].provider !== authProvider
  ) {
    throw new MedusaError(
      MedusaError.Types.UNAUTHORIZED,
      `Only ${authProvider} identities can create a user account for this authentication context`
    )
  }

  // Check if a user already exists for the identity-provider-verified email.
  const user = await query
    .graph({
      entity: "user",
      fields: ["id"],
      filters: {
        email: req.auth_context.user_metadata.email,
      },
    })
    .then((result) => result.data[0])

  // Link path: an existing user with a matching email is linked.
  if (user) {

View on GitHub (pinned to 5e06e544a2)

Solutions

  1. Use the same provider in the URL as the one used to obtain the JWT
  2. Inspect the auth identity's provider_identities (query auth provider identity) to confirm exactly one exists
  3. Unlink extra provider identities if multiple are attached
  4. Re-authenticate with the intended provider to mint a matching token

Example fix

// before
const token = await sdk.auth.authenticate('emailpass', {...})
await fetch('/auth/google/user', { headers: { Authorization: `Bearer ${token}` }, method: 'POST' })

// after
await fetch('/auth/emailpass/user', { headers: { Authorization: `Bearer ${token}` }, method: 'POST' })
Defensive patterns

Strategy: validation

Validate before calling

const claims = parseJwt(token)
const urlProvider = providerUsedToAuthenticate // track alongside token
if (claims.auth_provider !== urlProvider) throw new Error('provider mismatch')

Try / catch

catch (e) { if (e.type === 'unauthorized' && /identities can create/.test(e.message)) retryWithCorrectProvider() else throw e }

Prevention

When it happens

Trigger: Calling POST /auth/google/user with a token minted via emailpass; an identity that has zero or multiple provider identities (e.g. identity linked to two providers).

Common situations: Mismatch between URL provider segment and the provider actually used to authenticate; identities progressively linked to multiple providers; copy-pasted route from another provider's flow.

Understand the failure class

Related errors


AI-assisted analysis of medusajs/medusa@5e06e544a2 (2026-08-27). Data as JSON: /api/errors/d67d5aa00afff364. Report an issue: GitHub.