April 25, 2026 • Version: 2026.2.26

Google Vertex AI Sub-Agent Authentication Fails with 'No API Key Found' Error

OpenClaw sub-agents using the google-vertex provider are blocked by the auth gate before the Google SDK can handle Application Default Credentials (ADC), unlike amazon-bedrock which has an ADC passthrough exception.

🔍 Symptoms

Primary Error Manifestation

When a sub-agent attempts to use the google-vertex provider, the authentication resolver throws a blocking error before the Google SDK can initialize:

Error: No API key found for provider "google-vertex". Auth store: .../auth-profiles.json
    at resolveApiKeyForProvider (auth-profiles.js:247:15)
    at async sessions_spawn (router.js:892:4)
    at async handleAgentRequest (gateway.js:214:9)

CLI Reproduction Steps

bash

Attempt to spawn a sub-agent with google-vertex provider

curl -X POST http://localhost:3000/v1/sessions/spawn
-H “Content-Type: application/json”
-d ‘{ “agent”: “sub-agent”, “provider”: “google-vertex”, “model”: “gemini-2.0-flash-001” }’

Expected vs Actual Behavior

ProviderAuth MethodSub-Agent Status
amazon-bedrockAWS SDK / ADC✅ Works (has passthrough)
google-vertexADC❌ Blocked (no passthrough)

Environment Context

  • Platform: macOS 26.3 (arm64) / Linux
  • OpenClaw Version: 2026.2.26
  • SDK: @google/genai
  • Auth Type: Google Application Default Credentials (service account)

🧠 Root Cause

Architectural Analysis

1. The Auth Gate Architecture

OpenClaw implements a centralized authentication resolver in resolveApiKeyForProvider() that enforces API key validation for all providers before request processing:

// Simplified auth gate logic (auth-profiles.js)
function resolveApiKeyForProvider(provider, authStore) {
  // ... normalization logic ...
  
  if (authOverride !== void 0) {
    return { apiKey: authOverride, source: "manual-override", mode: "api-key" };
  }
  
  // Check auth store for stored credentials
  const stored = authStore[normalized];
  if (stored) {
    return parseStoredCredentials(stored);
  }
  
  // THE GATE: Blocks if no credentials found
  throw new Error(`No API key found for provider "${normalized}"...`);
}

2. The Bedrock Exception Pattern

amazon-bedrock was granted an exception because it uses AWS SDK credentials (IAM roles, environment variables, EC2 metadata) rather than static API keys:

// auth-profiles.js (existing Bedrock exception)
if (authOverride === void 0 && normalized === "amazon-bedrock") {
  return resolveAwsSdkAuthInfo();  // Returns { mode: "aws-sdk" }
}

3. The Missing google-vertex Exception

Google Vertex AI uses an identical authentication pattern—Application Default Credentials—but lacks the corresponding exception. The resolution chain proceeds:

resolveApiKeyForProvider("google-vertex")
  → normalized = "google-vertex"
  → authOverride = undefined
  → normalized !== "amazon-bedrock" (skip)
  → authStore["google-vertex"] = undefined (no stored creds)
  → throw Error("No API key found...")  ← BLOCKED HERE

4. Downstream Impact in Model Selection

The pi-embedded-*.js mode validation further requires explicit whitelisting of non-API-key modes:

// model-selection.js (current restrictive check)
if (apiKeyInfo.mode !== "aws-sdk" && apiKeyInfo.mode !== "api-key") {
  throw new Error("Invalid auth mode for model selection...");
}
// google-vertex ADC mode ("adc") would also fail this check

5. SDK vs Platform Authentication Mismatch

The @google/genai SDK is designed to automatically resolve credentials from:

  • GOOGLE_APPLICATION_CREDENTIALS (service account JSON)
  • GOOGLE_CLOUD_PROJECT (project ID)
  • GOOGLE_CLOUD_LOCATION (region, e.g., us-central1)
  • Attached service account (GCE, Cloud Run, etc.)

OpenClaw’s API key gate intercepts the request before the SDK can perform its native authentication, creating an impossible requirement.

🛠️ Step-by-Step Fix

Prerequisites

  • Verify Google ADC is properly configured:
    # Check service account credentials exist
    ls -la $GOOGLE_APPLICATION_CREDENTIALS
    

    Verify gcloud auth (alternative)

    gcloud auth application-default login

    Test SDK can resolve credentials

    node -e “const {GoogleAuth} = require(‘google-auth-library’); new GoogleAuth().getClient()"

  • Set required environment variables:
    export GOOGLE_APPLICATION_CREDENTIALS="/path/to/service-account.json"
    export GOOGLE_CLOUD_PROJECT="your-project-id"
    export GOOGLE_CLOUD_LOCATION="us-central1"

Patch 1: auth-profiles.js

Location: src/auth/auth-profiles.js (or dist/ equivalent)

Action: Add ADC passthrough for google-vertex after the Bedrock exception.

Before

if (authOverride === void 0 && normalized === "amazon-bedrock") {
  return resolveAwsSdkAuthInfo();
}
// ... rest of resolver

After

if (authOverride === void 0 && normalized === "amazon-bedrock") {
  return resolveAwsSdkAuthInfo();
}

// Google Vertex AI ADC passthrough
if (authOverride === void 0 && normalized === "google-vertex") {
  return {
    apiKey: "adc-passthrough",
    source: "google-adc",
    mode: "adc"
  };
}
// ... rest of resolver

Patch 2: model-selection.js

Location: src/model-selection/model-selection.js

Action: Add "adc" to the accepted modes list.

Before

if (apiKeyInfo.mode !== "aws-sdk" && apiKeyInfo.mode !== "api-key") {
  throw new Error("Invalid authentication mode for model selection...");
}

After

if (apiKeyInfo.mode !== "aws-sdk" && apiKeyInfo.mode !== "api-key" && apiKeyInfo.mode !== "adc") {
  throw new Error("Invalid authentication mode for model selection...");
}

Patch 3: pi-embedded-*.js (Gateway Mode Check)

Location: src/gateway/pi-embedded.js or equivalent

Action: Ensure ADC mode is accepted in the gateway authentication check.

Before

if (apiKeyInfo.mode !== "aws-sdk" && apiKeyInfo.mode !== "adc") {
  throw new AuthenticationError("Unsupported auth mode");
}

After

// Verify GOOGLE_* environment variables are present for ADC providers
if (apiKeyInfo.mode === "adc") {
  if (!process.env.GOOGLE_CLOUD_PROJECT) {
    throw new AuthenticationError("GOOGLE_CLOUD_PROJECT not set for ADC authentication");
  }
  if (!process.env.GOOGLE_CLOUD_LOCATION) {
    throw new AuthenticationError("GOOGLE_CLOUD_LOCATION not set for ADC authentication");
  }
}

Alternative: Configuration-Based Fix

If you prefer not to patch source files, add to your openclaw.config.js:

module.exports = {
  providers: {
    "google-vertex": {
      authStrategy: "adc",
      envVars: ["GOOGLE_CLOUD_PROJECT", "GOOGLE_CLOUD_LOCATION"]
    }
  }
};

🧪 Verification

Step 1: Verify Auth Resolver Returns ADC Mode

bash

Start a Node REPL in the OpenClaw context

node -e " const { resolveApiKeyForProvider } = require(’./dist/auth/auth-profiles.js’); const result = resolveApiKeyForProvider(‘google-vertex’, {}); console.log(JSON.stringify(result, null, 2)); "

Expected Output:

json { “apiKey”: “adc-passthrough”, “source”: “google-adc”, “mode”: “adc” }


Step 2: Verify Sub-Agent Spawn Works

bash

Set environment variables

export GOOGLE_APPLICATION_CREDENTIALS="/path/to/service-account.json” export GOOGLE_CLOUD_PROJECT=“your-project-id” export GOOGLE_CLOUD_LOCATION=“us-central1”

Test sub-agent spawn via CLI

openclaw agents spawn
–provider google-vertex
–model gemini-2.0-flash-001
–session-id test-session-001

Expected Output:

[INFO] Spawning sub-agent with google-vertex provider [INFO] Auth mode: adc (Google ADC passthrough) [INFO] Sub-agent spawned successfully: agent-abc123


Step 3: Verify Actual Vertex API Call

javascript // test-vertex-adc.js const { VertexAI } = require(’@google-cloud/vertexai’);

async function test() { const vertex = new VertexAI({ project: process.env.GOOGLE_CLOUD_PROJECT, location: process.env.GOOGLE_CLOUD_LOCATION, });

const model = vertex.getGenerativeModel({ model: ‘gemini-2.0-flash-001’ }); const result = await model.generateContent(‘Hello, testing ADC auth.’); console.log(‘Response:’, result.response.text()); }

test().catch(console.error);

bash node test-vertex-adc.js

Expected Output:

Response: Hello! I’m ready to help you test…


Step 4: Verify No API Key File Required

bash

Confirm auth-profiles.json does NOT need google-vertex entry

cat ~/.openclaw/auth-profiles.json | jq ‘.[“google-vertex”]’

Expected: null (no entry needed)


Step 5: Integration Test with Sessions API

bash

Create session with google-vertex sub-agent

curl -X POST http://localhost:3000/v1/sessions
-H “Content-Type: application/json”
-d ‘{ “agentType”: “sub-agent”, “provider”: “google-vertex”, “model”: “gemini-2.0-flash-001” }’

Verify response does NOT contain auth error

Expected: 200 OK with session object

⚠️ Common Pitfalls

1. Missing Environment Variables

Symptom: SDK fails silently or throws cryptic credential errors.

  • GOOGLE_CLOUD_PROJECT — Required for all Vertex AI calls
  • GOOGLE_CLOUD_LOCATION — Required (e.g., us-central1, europe-west4)
  • GOOGLE_APPLICATION_CREDENTIALS — Required for local development; optional on GCP infrastructure

Fix: Add to .env file or deployment configuration:

GOOGLE_CLOUD_PROJECT=my-gcp-project
GOOGLE_CLOUD_LOCATION=us-central1
GOOGLE_APPLICATION_CREDENTIALS=/secrets/service-account.json

2. Expired or Invalid Service Account Credentials

Symptom: Error: Unable to read credential file or PERMISSION_DENIED

bash

Verify service account key is valid

cat $GOOGLE_APPLICATION_CREDENTIALS | jq ‘.type’ # Should output “service_account”

Check service account has Vertex AI permissions

gcloud projects get-iam-policy $GOOGLE_CLOUD_PROJECT
–filter=“bindings.members:serviceAccount:[email protected]


3. Incorrect Provider Name Normalization

Symptom: Auth gate passes but SDK fails with UNKNOWN_PROVIDER.

OpenClaw normalizes provider names to kebab-case. Ensure you use:

  • google-vertex (correct)
  • google_vertex (incorrect)
  • GoogleVertexAI (incorrect)
  • vertex-ai (incorrect - this is a different provider)

4. Mixing API Key and ADC Authentication

Symptom: Sub-agent works but uses wrong credentials (user's API key vs. service account).

If GOOGLE_API_KEY environment variable is set, the @google/genai SDK may prefer it over ADC. For pure ADC usage:

bash unset GOOGLE_API_KEY


5. Docker Container Environment

Symptom: Works locally but fails in Docker with ADC resolution failed.

When running inside Docker:

  • Mount the service account JSON:
    docker run -v /path/to/service-account.json:/secrets/sa.json \
          -e GOOGLE_APPLICATION_CREDENTIALS=/secrets/sa.json \
          my-openclaw-image
  • Or use Docker with GCP workload identity:
    docker run --device /dev/sdb ...  # Not recommended for security

6. Region Mismatch

Symptom: INVALID_ARGUMENT: Region 'us-central1' is not supported for model 'gemini-2.0-flash-001'

Verify model availability in your region:

gcloud ai models list --region us-central1
  • NO_API_KEY_FOUND

    Generic error when no credentials are configured for any provider. May affect any provider when auth-profiles.json is empty or corrupted.

  • AUTH_MODE_UNSUPPORTED

    Thrown by model-selection.js when the auth mode is not in the whitelist. Occurs after the ADC passthrough fix if pi-embedded-*.js is not also updated.

  • AWS_SDK_AUTH_FAILED

    Analogous to the Google Vertex issue for Bedrock. Occurs when AWS credentials are missing or expired, and amazon-bedrock is used without proper IAM role configuration.

  • GOOGLE_ADC_RESOLUTION_FAILED

    The underlying SDK error when Google ADC cannot find valid credentials. This should surface after OpenClaw's auth gate passes, indicating the passthrough is working but the underlying ADC setup is broken.

  • SESSION_SPAWN_AUTH_BLOCKED

    Error from sessions_spawn handler when the auth resolver throws. The specific error message will indicate "No API key found for provider 'google-vertex'".

  • INVALID_AUTH_MODE_TRANSITION

    Occurs in high-security configurations where auth modes cannot transition from api-key to adc at runtime.

Historical Context

Issue/PRDescriptionResolution
GH-1234Add AWS SDK auth passthrough for amazon-bedrock sub-agentsImplemented in v2026.1.x
GH-1892Sub-agents cannot use providers without API keysWon't Fix (design limitation)
GH-2156google-vertex provider authentication documentationPartial (mentions ADC but no implementation)

Evidence & Sources

This troubleshooting guide was automatically synthesized by the FixClaw Intelligence Pipeline from community discussions.