Google Vertex AI in Practice

Production Error Handling for Vertex AI Calls in Python

A Claude call on Vertex AI can fail for Google reasons (IAM, quota, endpoint) or Anthropic reasons (request shape, payload size). Production code needs to tell them apart.

Claude 3P 101 · Updated July 2026 · Unofficial guide

When you call Claude through Vertex AI, your request passes through Google Cloud's front door before it reaches the model. That means two families of failure. Some errors are about the platform: the caller lacks an IAM permission, the model was never enabled in Model Garden, or you have exhausted a quota. Others are about the request itself: a payload over the 30 MB limit, messages that don't alternate user/assistant roles, or an image over 5 MB. Good error handling classifies the failure first and only then decides whether to retry.

Which exceptions you'll actually catch

Which exception type you see depends on which client you used. If you call Vertex through the AnthropicVertex SDK client — the usual choice — errors surface as the anthropic package's exception types, most usefully anthropic.APIStatusError, which carries a status_code attribute. If some of your code calls Vertex endpoints through Google's own client libraries instead, failures arrive as google.api_core.exceptions types (for example PermissionDenied or ResourceExhausted). Catch the family that matches the client making the call, and consult the official documentation for the full exception hierarchy of whichever SDK version you pin.

Map status codes to actions, not just messages

StatusLikely cause on VertexAction
401 / 403ADC missing or expired; caller lacks aiplatform.endpoints.predict (Vertex AI User role); model not enabled in Model GardenDon't retry. Fix credentials or IAM; alert an operator.
404Wrong model ID for this platform (e.g. a Bedrock-prefixed ID) or a model/endpoint mismatch for the chosen regionDon't retry. Fix configuration.
429Quota exhausted — requests-per-minute or tokens-per-minute for the model lineage in that locationRetry with exponential backoff; consider a quota increase or a second endpoint.
400Invalid request: oversized payload, bad role alternation, unsupported parameterDon't retry. Log the request shape and fix the caller.
5xxTransient service-side errorRetry with backoff and jitter.

The 429 case deserves emphasis. Vertex quotas for recent Claude models are shared per model lineage per location — all Opus versions draw from one bucket on the global endpoint, for instance — so a spike from one application can throttle another that shares the lineage. See the dedicated 429 article and quota types for the mechanics.

A retry skeleton

import json, logging, random, time
import anthropic
from anthropic import AnthropicVertex

client = AnthropicVertex(project_id="my-project", region="global")
RETRYABLE = {429, 500, 502, 503, 504}

def call_claude(messages, attempts=5):
    for attempt in range(attempts):
        try:
            return client.messages.create(model="claude-sonnet-5",
                                          max_tokens=1024, messages=messages)
        except anthropic.APIStatusError as e:
            if e.status_code in RETRYABLE and attempt < attempts - 1:
                time.sleep(min(2 ** attempt + random.random(), 30))
                continue
            logging.error(json.dumps({"event": "claude_call_failed",
                "status": e.status_code, "attempt": attempt}))
            raise

Two rules keep this skeleton honest. First, retries are for transient codes only — retrying a 403 just makes noise, and retrying a 400 resends a request that can never succeed. Second, cap total retry time; an agentic pipeline that silently retries for minutes is harder to debug than one that fails loudly.

Structured logs your future self can query

Emit one JSON log line per failed call: status code, model ID, endpoint region, attempt number, and the response message ID when you have one (Vertex IDs carry a msg_vrtx_ prefix, which makes them easy to grep). Never log prompt contents or credentials in error paths. Structured JSON matters on Google Cloud because Cloud Logging parses it into queryable fields — a week later, "how many 429s did the invoicing service see on Tuesday" becomes a filter, not an archaeology project. Pair these application logs with Cloud Audit Logs for the platform-side view.

Where to go next

For the catalogue of failure modes and their fixes, read common Vertex errors and diagnosing 403s. For availability engineering beyond retries, see multi-region failover strategies.

Sources