{"record":{"id":"7a9809cd304a9087","repo":"medusajs/medusa","slug":"could-not-verify-google-id-token-err-message","errorCode":null,"errorMessage":"Could not verify Google id_token: ${err.message}","messagePattern":"Could not verify Google id_token: (.+?)","errorType":"exception","errorClass":"MedusaError","httpStatus":401,"severity":"error","filePath":"packages/modules/providers/auth-google/src/services/google.ts","lineNumber":193,"sourceCode":"    authIdentityService: AuthIdentityProviderService\n  ) {\n    if (!idToken) {\n      return { success: false, error: \"No ID found\" }\n    }\n\n    let payload: JwtPayload\n    try {\n      const decoded = await verifyJwt(idToken, this.getSigningKey_, {\n        algorithms: [\"RS256\"],\n        audience: this.config_.clientId,\n        issuer: GOOGLE_ISSUERS,\n      })\n      if (!decoded || typeof decoded === \"string\") {\n        throw new Error(\"Invalid id_token\")\n      }\n      payload = decoded\n    } catch (err) {\n      throw new MedusaError(\n        MedusaError.Types.UNAUTHORIZED,\n        `Could not verify Google id_token: ${err.message}`\n      )\n    }\n\n    if (!payload.email_verified) {\n      throw new MedusaError(\n        MedusaError.Types.INVALID_DATA,\n        \"Email not verified, cannot proceed with authentication\"\n      )\n    }\n\n    if (!payload.sub) {\n      throw new MedusaError(\n        MedusaError.Types.INVALID_DATA,\n        \"id_token is missing 'sub' claim\"\n      )\n    }","sourceCodeStart":175,"sourceCodeEnd":211,"githubUrl":"https://github.com/medusajs/medusa/blob/5e06e544a296b9033f20f71f11c559f81a0e5739/packages/modules/providers/auth-google/src/services/google.ts#L175-L211","documentation":"After the token exchange, the provider verifies and decodes Google's signed id_token with the strategy's JWT verification (JWKS-based). If decoding/verification throws, the provider wraps the failure in an UNAUTHORIZED MedusaError including the underlying message.","triggerScenarios":"A malformed, tampered with, or expired id_token reaching verify_, or JWKS key lookup/audience/issuer checks failing during decoding.","commonSituations":"Client sending an id_token obtained for a different audience (client_id), clock skew causing expiry errors, transient JWKS fetch failures, or tokens from a different Google project.","solutions":["Ensure tokens come from the standard Google OAuth flow with the same client_id configured in the provider","Retry the flow — transient JWKS/network errors resolve themselves","Check the wrapped err.message to identify audience/expiry/signature mismatches and fix config accordingly"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { await provider.validateCallback(query) } catch (e) { if (e.type === 'unauthorized') { /* restart OAuth flow; possibly retry once for transient JWKS */ } else throw e }","preventionTips":["Always obtain id_tokens via the provider's own flow","Keep server clocks NTP-synced","Wrap auth callback handling to redirect to login on unauthorized errors"],"tags":["google","oauth","jwt","id-token","verification"],"backgroundTag":"jwt-verification-failed","analyzedSha":"5e06e544a296b9033f20f71f11c559f81a0e5739","analyzedAt":"2026-08-27T07:24:39.599Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}