{"record":{"id":"1348ba06f024c019","repo":"mongodb/node-mongodb-native","slug":"token-resource-must-be-set-in-the-auth-mechanism-p-1348ba","errorCode":null,"errorMessage":"TOKEN_RESOURCE must be set in the auth mechanism properties when ENVIRONMENT is gcp.","messagePattern":"TOKEN_RESOURCE must be set in the auth mechanism properties when ENVIRONMENT is gcp\\.","errorType":"exception","errorClass":"MongoGCPError","httpStatus":null,"severity":"critical","filePath":"src/cmap/auth/mongodb_oidc/gcp_machine_workflow.ts","lineNumber":26,"sourceCode":"\n/** GCP request headers. */\nconst GCP_HEADERS = Object.freeze({ 'Metadata-Flavor': 'Google' });\n\n/** Error for when the token audience is missing in the environment. */\nconst TOKEN_RESOURCE_MISSING_ERROR =\n  'TOKEN_RESOURCE must be set in the auth mechanism properties when ENVIRONMENT is gcp.';\n\n/**\n * The callback function to be used in the automated callback workflow.\n * @param params - The OIDC callback parameters.\n * @returns The OIDC response.\n */\nexport const gcpCallback: OIDCCallbackFunction = async (\n  params: OIDCCallbackParams\n): Promise<OIDCResponse> => {\n  const tokenAudience = params.tokenAudience;\n  if (!tokenAudience) {\n    throw new MongoGCPError(TOKEN_RESOURCE_MISSING_ERROR);\n  }\n  return await getGcpTokenData(tokenAudience);\n};\n\n/**\n * Hit the GCP endpoint to get the token data.\n */\nasync function getGcpTokenData(tokenAudience: string): Promise<OIDCResponse> {\n  const url = new URL(GCP_BASE_URL);\n  url.searchParams.append('audience', tokenAudience);\n  const response = await get(url, {\n    headers: GCP_HEADERS\n  });\n  if (response.status !== 200) {\n    throw new MongoGCPError(\n      `Status code ${response.status} returned from the GCP endpoint. Response body: ${response.body}`\n    );\n  }","sourceCodeStart":8,"sourceCodeEnd":44,"githubUrl":"https://github.com/mongodb/node-mongodb-native/blob/dce7939f86fb283e167ad709955abedb7bf23124/src/cmap/auth/mongodb_oidc/gcp_machine_workflow.ts#L8-L44","documentation":"Thrown by the GCP OIDC machine workflow (gcp_machine_workflow.ts:26) when the TOKEN_RESOURCE mechanism property is missing. The driver needs TOKEN_RESOURCE as the audience query parameter for the GCP metadata endpoint (http://metadata/computeMetadata/v1/instance/service-accounts/default/identity) that mints OIDC tokens. Without it the driver cannot request a token scoped to your MongoDB cluster. It is raised as a MongoGCPError after the tokenAudience param is found falsy inside the gcpCallback.","triggerScenarios":"Connecting with authMechanism='MONGODB-OIDC' and authMechanismProperties.ENVIRONMENT='gcp' while omitting the TOKEN_RESOURCE property; or passing an empty/falsy TOKEN_RESOURCE whose value does not propagate into params.tokenAudience (automated_callback_workflow.ts:72-73). Note MongoCredentials also validates this earlier at mongo_credentials.ts:211, so reaching this exact line usually means the credentials object was built bypassing that check.","commonSituations":"Copying an Azure OIDC connection string and changing ENVIRONMENT to gcp without adding the gcp TOKEN_RESOURCE. URL-encoding the mechanism properties so the colon-delimited TOKEN_RESOURCE is parsed as empty. Mixing up the property names (TOKEN_RESOURCE vs AUDIENCE).","solutions":["Add TOKEN_RESOURCE to authMechanismProperties: ...&authMechanismProperties=ENVIRONMENT:gcp,TOKEN_RESOURCE:<your-atlas-audience>","Confirm the TOKEN_RESOURCE value exactly equals the audience configured on your Atlas OIDC workload identity provider","Check the connection string is not URL-encoding the colon between ENVIRONMENT/TOKEN_RESOURCE keys and values","Verify mechanismProperties.TOKEN_RESOURCE reaches credentials by logging it before connect"],"exampleFix":"// before\nconst uri = 'mongodb://host/?authMechanism=MONGODB-OIDC&authMechanismProperties=ENVIRONMENT:gcp';\n\n// after\nconst uri =\n  'mongodb://host/?authMechanism=MONGODB-OIDC&authMechanismProperties=ENVIRONMENT:gcp,TOKEN_RESOURCE:https://cluster.example.mongodb.net';","handlingStrategy":"validation","validationCode":"const mp = clientOptions.auth?.mechanismProperties ?? {};\nif (mp.ENVIRONMENT === 'gcp' && !mp.TOKEN_RESOURCE) {\n  throw new Error('TOKEN_RESOURCE is required for OIDC ENVIRONMENT=gcp');\n}\n// or, from a connection string, parse and assert before constructing MongoClient.","typeGuard":"function hasGcpTokenResource(mp: Record<string, unknown>): mp is { TOKEN_RESOURCE: string } {\n  return typeof mp.TOKEN_RESOURCE === 'string' && mp.TOKEN_RESOURCE.length > 0;\n}","tryCatchPattern":"try {\n  await client.connect();\n} catch (err) {\n  if (err instanceof MongoGCPError && /TOKEN_RESOURCE/.test(err.message)) {\n    // fix the connection string / mechanismProperties and retry\n  } else throw err;\n}","preventionTips":["Centralize OIDC connection-string building in one helper that always sets TOKEN_RESOURCE for gcp/azure","Assert mechanismProperties in a startup config validation step before connecting","Document the per-environment required properties next to your deployment config"],"tags":["oidc","gcp","authentication","configuration"],"backgroundTag":null,"analyzedSha":"dce7939f86fb283e167ad709955abedb7bf23124","analyzedAt":"2026-08-11T04:54:53.215Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}