Skip to content

Vertex AI cannot authenticate with Application Default Credentials: an API key is required, and any key value disables ADC #9016

Description

@axiom-of-choice

What happened?

Vertex AI auth cannot use Application Default Credentials. It requires an API key, and the only way to satisfy that requirement produces a 401 from Vertex.

With ADC correctly configured (GOOGLE_APPLICATION_CREDENTIALS pointing at a service account key, plus GOOGLE_CLOUD_PROJECT, GOOGLE_CLOUD_LOCATION, GOOGLE_GENAI_USE_VERTEXAI=true) and a custom model entry:

{
  "modelProviders": {
    "vertex-ai": [{ "id": "gemini-2.5-pro", "name": "Gemini 2.5 Pro" }]
  }
}

startup fails with:

Missing credentials for modelProviders model 'gemini-2.5-pro'. Configure modelProviders.vertex-ai[].envKey and set that environment variable.

Following that message and adding an envKey whose variable holds a placeholder value then fails at request time:

API Error: 401 {"error": {"code": 401, "message": "API keys are not supported by this API. Expected OAuth2 access token or other authentication credentials that assert a principal. See https://cloud.google.com/docs/authentication", "status": "UNAUTHENTICATED", "details": [{"reason": "CREDENTIALS_MISSING", "domain": "googleapis.com", "metadata": {"method": "google.cloud.aiplatform.v1beta1.PredictionService.StreamGenerateContent", "service": "aiplatform.googleapis.com"}}]}}

So the two reachable states are "no credentials" and "wrong kind of credentials", with nothing in between. This is not specific to modelProviders: plain vertex-ai auth with no custom entry is rejected the same way, because the only credential the auth path accepts is GOOGLE_API_KEY.

What did you expect to happen?

vertex-ai auth to accept Application Default Credentials when a Google Cloud project is configured, with no API key and no envKey, the same way the Google SDK does on its own. The provider documentation says selecting vertex-ai uses the @google/genai SDK in Vertex AI mode, which implies the SDK's own credential resolution, and ADC is the standard way to authenticate to Vertex.

Root cause

Two validation gates require an API key for vertex-ai, and the SDK then treats whatever is supplied as an Express mode key.

  1. validateModelConfig in packages/core/src/core/contentGenerator.ts returns early only for Qwen OAuth. Every other auth type, including vertex-ai, reaches if (!config.apiKey) and errors. In strict modelProviders selection that produces the first message above.
  2. validateAuthMethod in packages/cli/src/config/auth.ts sends USE_VERTEX_AI straight to the API key check, whose default variable is GOOGLE_API_KEY. Nothing in the auth path reads GOOGLE_CLOUD_PROJECT or GOOGLE_APPLICATION_CREDENTIALS.
  3. In @google/genai 2.6.0, the version this repo pins, an explicitly passed apiKey takes precedence over project and location from the environment and clears them. The client then sends x-goog-api-key against aiplatform.googleapis.com, which is exactly what returns CREDENTIALS_MISSING.

Point 3 means the placeholder workaround cannot work in principle: passing any API key value is precisely what disables ADC.

Reproduction of point 3 with no network and no credentials, against the pinned SDK version:

import { GoogleGenAI } from '@google/genai'; // 2.6.0

process.env['GOOGLE_GENAI_USE_VERTEXAI'] = 'true';
process.env['GOOGLE_CLOUD_PROJECT'] = 'demo-project';
process.env['GOOGLE_CLOUD_LOCATION'] = 'global';

for (const opts of [{ apiKey: 'placeholder' }, {}]) {
  const c = new GoogleGenAI(opts).apiClient.clientOptions;
  console.log({
    project: c.project,
    location: c.location,
    apiKey: c.apiKey,
    auth: c.auth.apiKey !== undefined ? 'x-goog-api-key' : 'ADC/OAuth2',
  });
}
The user provided Vertex AI API key will take precedence over the project/location from the environment variables.
{ project: undefined, location: undefined, apiKey: 'placeholder', auth: 'x-goog-api-key' }
{ project: 'demo-project', location: 'global', apiKey: undefined, auth: 'ADC/OAuth2' }

The ADC path already works one layer below the validation. createGeminiContentGenerator passes apiKey through unchanged, so an undefined key is all the SDK needs to resolve ADC itself.

Client information

Client Information
$ qwen --version
0.21.10

macOS 26.5.2 (arm64), Node v26.5.0. The code paths above were also read on main at 50097c1.

Login information

Vertex AI (vertex-ai), authenticating with a service account key through GOOGLE_APPLICATION_CREDENTIALS.

Anything else we need to know?

A related observation while tracing this: ContentGeneratorConfig.vertexai is declared and read in createGeminiContentGenerator, but never assigned by any caller, so Vertex mode currently depends entirely on validateAuthMethod setting GOOGLE_GENAI_USE_VERTEXAI as a side effect.

Happy to send a PR for this.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    category/authenticationAuthentication and authorizationpriority/P2Medium - Moderately impactful, noticeable problemscope/google-authGoogle-specific authenticationtype/bugSomething isn't working as expected

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions