{"record":{"id":"07f34117b7bc5afa","repo":"medusajs/medusa","slug":"oidc-provider-requires-a-callback-url-option","errorCode":null,"errorMessage":"OIDC provider requires a 'callback_url' option","messagePattern":"OIDC provider requires a 'callback_url' option","errorType":"validation","errorClass":"MedusaError","httpStatus":400,"severity":"critical","filePath":"packages/modules/providers/auth-oidc/src/services/oidc.ts","lineNumber":51,"sourceCode":"  static validateOptions(options: OidcAuthProviderOptions) {\n    if (!options.issuer) {\n      throw new MedusaError(\n        MedusaError.Types.INVALID_DATA,\n        \"OIDC provider requires an 'issuer' option\"\n      )\n    }\n\n    assertSecureUrl(options.issuer, \"issuer\")\n\n    if (!options.client_id) {\n      throw new MedusaError(\n        MedusaError.Types.INVALID_DATA,\n        \"OIDC provider requires a 'client_id' option\"\n      )\n    }\n\n    if (!options.callback_url) {\n      throw new MedusaError(\n        MedusaError.Types.INVALID_DATA,\n        \"OIDC provider requires a 'callback_url' option\"\n      )\n    }\n  }\n\n  constructor(\n    { logger, cache }: InjectedDependencies,\n    options: OidcAuthProviderOptions\n  ) {\n    // @ts-ignore\n    super(...arguments)\n    this.config_ = options\n    this.logger_ = logger\n    this.engine_ = new OidcEngine(options, cache)\n  }\n\n  // The same OIDC package is registered once per IdP (okta, auth0, ...), so the","sourceCodeStart":33,"sourceCodeEnd":69,"githubUrl":"https://github.com/medusajs/medusa/blob/5e06e544a296b9033f20f71f11c559f81a0e5739/packages/modules/providers/auth-oidc/src/services/oidc.ts#L33-L69","documentation":"validateOptions throws INVALID_DATA when callback_url is absent. This is the URL the IdP redirects to after authentication and must match what is registered with the provider.","triggerScenarios":"Provider options omit callback_url or reference an unset env var; Medusa therefore fails validation during registration of the auth provider at boot.","commonSituations":"Forgetting that OIDC (unlike other strategies) requires an explicit callback_url; changing the public host/port without updating the callback env var; mismatch between the configured URL and the IdP's registered redirect URI list (the latter surfaces later as an IdP-side error, so configure them together).","solutions":["Add callback_url pointing at your Medusa auth callback route (customer: https://<host>/auth/customer/<provider-id>/callback; admin: the admin callback route).","Register the exact same URL (scheme, host, port, path) in the IdP's allowed redirect URIs.","Use env vars per environment so local (http://localhost:8000/...) and production URLs don't collide."],"exampleFix":"// before\noptions: { issuer: \"...\", client_id: \"...\" }\n// after\noptions: { issuer: \"...\", client_id: \"...\", callback_url: `${process.env.MEDUSA_BACKEND_URL}/auth/customer/google/callback` }","handlingStrategy":"validation","validationCode":"if (!process.env.OIDC_CALLBACK_URL) {\n  throw new Error(\"OIDC_CALLBACK_URL is not set; cannot configure the oidc auth provider\")\n}","typeGuard":"const hasCallbackUrl = (o: Partial<OidcAuthProviderOptions>): o is OidcAuthProviderOptions =>\n  typeof o.callback_url === \"string\" && o.callback_url.length > 0","tryCatchPattern":"try { OidcAuthService.validateOptions(options) } catch (e) { if (e instanceof MedusaError && /'callback_url'/.test(e.message)) { /* report config error */ } throw e }","preventionTips":["Derive callback_url from one MEDUSA_BACKEND_URL env var per environment.","Mirror the exact URL in the IdP's redirect URI list.","Add callback_url to your config smoke test."],"tags":["oidc","configuration","startup","callback-url"],"backgroundTag":"missing-config-option","analyzedSha":"5e06e544a296b9033f20f71f11c559f81a0e5739","analyzedAt":"2026-08-27T07:24:39.599Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}