One of the most frustrating moments when building with Vertex AI and Gemini is getting authentication errors after you've already set everything up. "The API key is valid, so why is access being denied?" "It works locally but fails on Cloud Run"—these are symptoms that almost always trace back to misconfigured service accounts or Application Default Credentials (ADC).
Common Authentication Error Symptoms
Vertex AI + Gemini auth errors generally fall into four patterns.
Pattern 1: PERMISSION_DENIED error
google.api_core.exceptions.PermissionDenied: 403 Permission 'aiplatform.endpoints.predict' denied on resource
This happens when the service account hasn't been granted the necessary IAM roles.
Pattern 2: UNAUTHENTICATED error
google.api_core.exceptions.Unauthenticated: 401 Request had invalid authentication credentials.
Expected OAuth 2 access token, login cookie or other valid authentication credential.
This appears when credentials are missing, expired, or malformed.
Pattern 3: ADC (Application Default Credentials) not found
google.auth.exceptions.DefaultCredentialsError: Your default credentials were not found.
To set up Application Default Credentials, see https://cloud.google.com/docs/authentication/external/set-up-adc
Common in local dev environments or CI/CD pipelines where gcloud auth application-default login hasn't been run.
Pattern 4: Service account key file can't be loaded
FileNotFoundError: [Errno 2] No such file or directory: '/path/to/service-account-key.json'
ValueError: Service account info was not in the expected format, missing fields: token_uri
The GOOGLE_APPLICATION_CREDENTIALS environment variable points to the wrong path, or the JSON file is corrupted.
Root Cause Analysis: Why These Errors Happen
Vertex AI is different from the standard Gemini API (generativelanguage.googleapis.com). It's a Google Cloud service governed by IAM, which means authentication and authorization work differently. Misunderstanding this is the root cause of most auth issues.
The five most common causes are:
- Missing IAM role: The service account doesn't have the
Vertex AI Userrole (roles/aiplatform.user) - ADC not configured:
gcloud auth application-default loginhasn't been run, or stale credentials are cached - Project ID mismatch: The
projectspecified in code doesn't match the project the service account belongs to - Missing region specification: Vertex AI uses regional endpoints—you must specify a location like
us-central1 - API not enabled: The Vertex AI API hasn't been enabled in Google Cloud Console
Step-by-Step Fix
Step 1: Enable the Vertex AI API
Before anything else, make sure the API is enabled in your project.
# Check if it's already enabled
gcloud services list --enabled --project YOUR_PROJECT_ID | grep aiplatform
# Enable it if needed
gcloud services enable aiplatform.googleapis.com --project YOUR_PROJECT_IDStep 2: Create a Service Account and Assign IAM Roles
# Create the service account
gcloud iam service-accounts create gemini-sa \
--display-name="Gemini Service Account" \
--project=YOUR_PROJECT_ID
# Grant the Vertex AI User role
gcloud projects add-iam-policy-binding YOUR_PROJECT_ID \
--member="serviceAccount:gemini-sa@YOUR_PROJECT_ID.iam.gserviceaccount.com" \
--role="roles/aiplatform.user"
# Add Storage read access if needed
gcloud projects add-iam-policy-binding YOUR_PROJECT_ID \
--member="serviceAccount:gemini-sa@YOUR_PROJECT_ID.iam.gserviceaccount.com" \
--role="roles/storage.objectViewer"Step 3: Set Up ADC for Local Development (User Account)
For local development, using ADC with your personal Google account is recommended over service account keys.
# Log in with your user account (opens a browser)
gcloud auth application-default login
# Set the default project
gcloud config set project YOUR_PROJECT_ID
# Verify the token works
gcloud auth application-default print-access-tokenStep 4: Use a Service Account Key (Production / CI/CD)
When service account keys are necessary, handle them securely and set them via environment variables.
# Generate a key file
gcloud iam service-accounts keys create key.json \
--iam-account=gemini-sa@YOUR_PROJECT_ID.iam.gserviceaccount.com
# Set the environment variable
export GOOGLE_APPLICATION_CREDENTIALS="/absolute/path/to/key.json"import vertexai
from vertexai.generative_models import GenerativeModel
# Always specify project and location explicitly
vertexai.init(project="YOUR_PROJECT_ID", location="us-central1")
model = GenerativeModel("gemini-2.5-pro-preview-03-25")
response = model.generate_content("Hello from Vertex AI!")
print(response.text)
# Expected output: "Hello! How can I help you today?"Step 5: Cloud Run / GKE — Attach a Service Account to the Instance
For Cloud Run and GKE, the best practice is to attach a service account directly to the instance. No key files needed, and it's far more secure.
# Deploy Cloud Run with a service account attached
gcloud run deploy my-service \
--image gcr.io/YOUR_PROJECT_ID/my-image \
--service-account gemini-sa@YOUR_PROJECT_ID.iam.gserviceaccount.com \
--region us-central1 \
--project YOUR_PROJECT_IDIn your Python code, no credential configuration is needed at all:
import vertexai
from vertexai.generative_models import GenerativeModel
# On Cloud Run, credentials are fetched automatically from the metadata server
vertexai.init(project="YOUR_PROJECT_ID", location="us-central1")
model = GenerativeModel("gemini-2.5-pro-preview-03-25")
response = model.generate_content("Hello from Cloud Run!")
print(response.text)Step 6: Check Your SDK Version
Older versions of the SDK may have different auth behavior. Keep it updated.
# Check current version
pip show google-cloud-aiplatform
# Upgrade to latest
pip install --upgrade google-cloud-aiplatform
# With LangChain support
pip install google-cloud-aiplatform[langchain]How to Verify the Fix
Run this diagnostic script to confirm your auth setup is working correctly.
import vertexai
from vertexai.generative_models import GenerativeModel
import google.auth
# Check what credentials are currently active
credentials, project = google.auth.default()
print(f"Credential type: {type(credentials).__name__}")
print(f"Project ID: {project}")
# Test the Vertex AI connection
try:
vertexai.init(project="YOUR_PROJECT_ID", location="us-central1")
model = GenerativeModel("gemini-2.0-flash-001")
response = model.generate_content("Test: what is 1+1?")
print(f"✅ Auth successful! Response: {response.text}")
except Exception as e:
print(f"❌ Auth error: {e}")Expected output:
Credential type: google.oauth2.credentials.Credentials
Project ID: your-project-id
✅ Auth successful! Response: 1+1 equals 2.
Prevention: Best Practices to Avoid Recurrence
Follow the principle of least privilege: Don't assign roles/owner when roles/aiplatform.user is all you need. Always grant the minimum permissions required.
Never hardcode credentials in source code: Embedding key paths or content in your code risks leaking them to version control. Use environment variables or Google Cloud Secret Manager instead.
# ❌ Never do this
credentials_info = {
"type": "service_account",
"project_id": "YOUR_PROJECT_ID",
# Don't paste key content here
}
# ✅ Let GOOGLE_APPLICATION_CREDENTIALS do the work
# Just call vertexai.init() — no credential code neededRotate service account keys regularly: Google recommends rotating keys every 90 days. Set up automated key rotation using Google Cloud's built-in tooling.
Use Workload Identity on GKE: Workload Identity lets you bind a Kubernetes service account to a Google Cloud service account, eliminating the need for key files entirely. This is the gold standard for securing GKE workloads.
Looking back
Most Vertex AI + Gemini authentication errors boil down to one of these issues: a missing IAM role, unconfigured ADC, or a mismatched project ID. Once you understand which pattern you're dealing with, the fix is usually straightforward.
To recap the recommended approach by environment:
- Local development → use
gcloud auth application-default login - Cloud Run / GCE → attach a service account to the instance
- GKE → use Workload Identity
- External CI/CD (GitHub Actions, etc.) → use Workload Identity Federation