Skip to content

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

TypePurposeKey Fields
ErrorInfoMachine-readable error reasonreason, domain, metadata
BadRequestField-level validation errorsfield_violations[].field, field_violations[].description
RetryInfoWhen to retryretry_delay
HelpDocumentation linkslinks[].url, links[].description
LocalizedMessageLocalized user-facing messagelocale, message
DebugInfoServer-side debug datastack_entries[], detail
PreconditionFailureFailed preconditionsviolations[].type, violations[].subject
QuotaFailureQuota exceeded detailsviolations[].subject, violations[].description
ResourceInfoInfo about the failed resourceresource_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 CodeHTTP CodeStatusRetry?Description
0200OKN/ASuccess
1499CANCELLEDNoClient cancelled
2500UNKNOWNYesUnknown server error
3400INVALID_ARGUMENTNoMalformed request
4504DEADLINE_EXCEEDEDYesTimeout
5404NOT_FOUNDNoResource not found
6409ALREADY_EXISTSNoDuplicate resource
7403PERMISSION_DENIEDNoInsufficient permissions
8429RESOURCE_EXHAUSTEDYesRate limited or quota exceeded
9400FAILED_PRECONDITIONNoPrecondition not met
10409ABORTEDYesConflict (e.g., read-modify-write)
11400OUT_OF_RANGENoValue outside valid range
12501UNIMPLEMENTEDNoMethod not implemented
13500INTERNALYesInternal server error
14503UNAVAILABLEYesService temporarily unavailable
15500DATA_LOSSNoUnrecoverable data loss
16401UNAUTHENTICATEDNoMissing/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

  1. Always check error.details for machine-readable reasons (ErrorInfo)
  2. Use reason for programmatic handling, not message (which may change)
  3. Implement retry only for retryable codes (429, 500, 503, 504)
  4. Log the full error response including details for debugging
  5. Use client libraries that handle retries automatically

See Also