medusajs/medusa · critical · MedusaError

OIDC engine requires an 'issuer' option

Error message

OIDC engine requires an 'issuer' option

What it means

The OIDC auth provider's engine (openid-client wrapper) requires an `issuer` option — the URL of the OIDC provider's configuration endpoint. The constructor throws INVALID_DATA when it is missing, failing at startup.

Source

Thrown at packages/modules/providers/auth-oidc/src/engine/engine.ts:65

  protected readonly options_: OidcEngineOptions
  protected readonly discoveryCacheTtlMs_: number
  protected readonly httpTimeoutMs_: number
  protected readonly cache_?: ICacheService

  /**
   * The memoized OIDC client. `openid-client` v5 caches the JWKS keystore per
   * `Issuer` instance, so building a fresh client on every call would refetch
   * the JWKS over HTTP on every login callback. The client is built lazily and
   * reused until the discovery cache entry expires; when all endpoints are
   * configured explicitly (no discovery), it's cached indefinitely, since the
   * engine's options are immutable per instance.
   */
  protected clientPromise_?: Promise<Client>
  protected clientExpiresAt_ = 0

  constructor(options: OidcEngineOptions, cache?: ICacheService) {
    if (!options?.issuer) {
      throw new MedusaError(
        MedusaError.Types.INVALID_DATA,
        "OIDC engine requires an 'issuer' option"
      )
    }
    if (!options.client_id) {
      throw new MedusaError(
        MedusaError.Types.INVALID_DATA,
        "OIDC engine requires a 'client_id' option"
      )
    }
    if (!options.callback_url) {
      throw new MedusaError(
        MedusaError.Types.INVALID_DATA,
        "OIDC engine requires a 'callback_url' option"
      )
    }

    assertSecureUrl(options.issuer, "issuer")

View on GitHub (pinned to 5e06e544a2)

Solutions

  1. Set issuer to the IdP's base URL, e.g. https://accounts.google.com or https://yourorg.okta.com — the engine appends /.well-known/openid-configuration itself
  2. Verify the URL resolves by opening {issuer}/.well-known/openid-configuration in a browser
  3. Check the env var feeding issuer is set in the runtime environment

Example fix

// before
{ id: 'oidc', resolve: '@medusajs/auth-oidc', options: { client_id, client_secret, callback_url } }
// after
{ id: 'oidc', resolve: '@medusajs/auth-oidc', options: { issuer: process.env.OIDC_ISSUER, client_id, client_secret, callback_url } }
Defensive patterns

Strategy: validation

Validate before calling

const issuer = process.env.OIDC_ISSUER
if (!issuer || !URL.parse(issuer)) throw new Error('OIDC_ISSUER must be the IdP base URL')

Prevention

When it happens

Trigger: Configuring the auth-oidc provider whose options are forwarded to the engine without an `issuer`, e.g. only passing client_id/secret.

Common situations: Missing or misnamed issuer env var, using a discovery URL that isn't the base issuer URL (e.g. including /.well-known/openid-configuration), or the IdP not supporting OIDC discovery.

Related errors


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