Error Handling (AIP-193)
✅ Fresh -- Updated March 2026 from official Google Cloud API Design Guide.
Overview
Google Cloud APIs use a consistent error model based on google.rpc.Status. Every error response includes a canonical error code, a human-readable message, and optional structured details.
Error Response Structure
gRPC Error Model
google.rpc.Status {
int32 code // Canonical error code (e.g., 5 = NOT_FOUND)
string message // Human-readable error description
repeated Any details // Structured error details
}HTTP/JSON Error Format
json
{
"error": {
"code": 404,
"status": "NOT_FOUND",
"message": "Requested entity was not found.",
"details": [
{
"@type": "type.googleapis.com/google.rpc.ErrorInfo",
"reason": "RESOURCE_NOT_FOUND",
"domain": "googleapis.com",
"metadata": {
"resource": "projects/my-project/topics/my-topic"
}
}
]
}
}Error Detail Types
| Type | Purpose | Key Fields |
|---|---|---|
ErrorInfo | Machine-readable error reason | reason, domain, metadata |
BadRequest | Field-level validation errors | field_violations[].field, field_violations[].description |
RetryInfo | When to retry | retry_delay |
Help | Documentation links | links[].url, links[].description |
LocalizedMessage | Localized user-facing message | locale, message |
DebugInfo | Server-side debug data | stack_entries[], detail |
PreconditionFailure | Failed preconditions | violations[].type, violations[].subject |
QuotaFailure | Quota exceeded details | violations[].subject, violations[].description |
ResourceInfo | Info about the failed resource | resource_type, resource_name |
ErrorInfo in Detail
ErrorInfo is the most important error detail. It provides a machine-readable reason that code can act on:
json
{
"@type": "type.googleapis.com/google.rpc.ErrorInfo",
"reason": "API_KEY_INVALID",
"domain": "googleapis.com",
"metadata": {
"service": "translate.googleapis.com",
"consumer": "projects/12345"
}
}- reason: A unique, stable error reason (e.g.,
API_KEY_INVALID,QUOTA_EXCEEDED) - domain: The error domain (usually
googleapis.com) - metadata: Additional key-value context
Canonical Error Codes
Full Error Code Table
| gRPC Code | HTTP Code | Status | Retry? | Description |
|---|---|---|---|---|
| 0 | 200 | OK | N/A | Success |
| 1 | 499 | CANCELLED | No | Client cancelled |
| 2 | 500 | UNKNOWN | Yes | Unknown server error |
| 3 | 400 | INVALID_ARGUMENT | No | Malformed request |
| 4 | 504 | DEADLINE_EXCEEDED | Yes | Timeout |
| 5 | 404 | NOT_FOUND | No | Resource not found |
| 6 | 409 | ALREADY_EXISTS | No | Duplicate resource |
| 7 | 403 | PERMISSION_DENIED | No | Insufficient permissions |
| 8 | 429 | RESOURCE_EXHAUSTED | Yes | Rate limited or quota exceeded |
| 9 | 400 | FAILED_PRECONDITION | No | Precondition not met |
| 10 | 409 | ABORTED | Yes | Conflict (e.g., read-modify-write) |
| 11 | 400 | OUT_OF_RANGE | No | Value outside valid range |
| 12 | 501 | UNIMPLEMENTED | No | Method not implemented |
| 13 | 500 | INTERNAL | Yes | Internal server error |
| 14 | 503 | UNAVAILABLE | Yes | Service temporarily unavailable |
| 15 | 500 | DATA_LOSS | No | Unrecoverable data loss |
| 16 | 401 | UNAUTHENTICATED | No | Missing/invalid credentials |
Retry Strategy
Exponential backoff with jitter:
python
import time
import random
def retry_with_backoff(func, max_retries=5, base_delay=1.0, max_delay=60.0):
for attempt in range(max_retries):
try:
return func()
except Exception as e:
if not is_retryable(e):
raise
delay = min(base_delay * (2 ** attempt) + random.uniform(0, 1), max_delay)
time.sleep(delay)
raise Exception("Max retries exceeded")TIP
Google Cloud client libraries implement automatic retry with exponential backoff. Use them instead of writing your own retry logic.
Best Practices for API Consumers
- Always check
error.detailsfor machine-readable reasons (ErrorInfo) - Use
reasonfor programmatic handling, notmessage(which may change) - Implement retry only for retryable codes (429, 500, 503, 504)
- Log the full error response including details for debugging
- Use client libraries that handle retries automatically
See Also
- Error Codes Reference -- Quick lookup table
- Troubleshooting -- Common error resolutions
- Standard Methods -- Expected error codes per method