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.
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.
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.
- 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
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.
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_CREDENTIALSpointing at a service account key, plusGOOGLE_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:
Following that message and adding an
envKeywhose variable holds a placeholder value then fails at request time:So the two reachable states are "no credentials" and "wrong kind of credentials", with nothing in between. This is not specific to
modelProviders: plainvertex-aiauth with no custom entry is rejected the same way, because the only credential the auth path accepts isGOOGLE_API_KEY.What did you expect to happen?
vertex-aiauth to accept Application Default Credentials when a Google Cloud project is configured, with no API key and noenvKey, the same way the Google SDK does on its own. The provider documentation says selectingvertex-aiuses the@google/genaiSDK 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.validateModelConfiginpackages/core/src/core/contentGenerator.tsreturns early only for Qwen OAuth. Every other auth type, includingvertex-ai, reachesif (!config.apiKey)and errors. In strictmodelProvidersselection that produces the first message above.validateAuthMethodinpackages/cli/src/config/auth.tssendsUSE_VERTEX_AIstraight to the API key check, whose default variable isGOOGLE_API_KEY. Nothing in the auth path readsGOOGLE_CLOUD_PROJECTorGOOGLE_APPLICATION_CREDENTIALS.@google/genai2.6.0, the version this repo pins, an explicitly passedapiKeytakes precedence over project and location from the environment and clears them. The client then sendsx-goog-api-keyagainstaiplatform.googleapis.com, which is exactly what returnsCREDENTIALS_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:
The ADC path already works one layer below the validation.
createGeminiContentGeneratorpassesapiKeythrough unchanged, so an undefined key is all the SDK needs to resolve ADC itself.Client information
Client Information
macOS 26.5.2 (arm64), Node v26.5.0. The code paths above were also read on
mainat 50097c1.Login information
Vertex AI (
vertex-ai), authenticating with a service account key throughGOOGLE_APPLICATION_CREDENTIALS.Anything else we need to know?
A related observation while tracing this:
ContentGeneratorConfig.vertexaiis declared and read increateGeminiContentGenerator, but never assigned by any caller, so Vertex mode currently depends entirely onvalidateAuthMethodsettingGOOGLE_GENAI_USE_VERTEXAIas a side effect.Happy to send a PR for this.