Skip to content

Error Handling

Your clients are getting errors. This page tells you when to retry, how to correlate failures across systems, and what to include when reporting issues.

Every error includes an id, code, kind, and optional retry hint — the same fields regardless of channel. The full field spec and all 16 error kinds are in the Error Contract reference. For the complete list of error codes, see the Error Catalog.

Retry Decision

When to retry failed requests

Request failed
Is the error retryable?
Yes
1 Wait (backoff)
2 Retry request
3 Max 3 attempts
No
Report error to caller
Retryable
  • 503 Service Unavailable
  • 429 Too Many Requests
  • Connection timeout
Not retryable
  • 400 Bad Request
  • 401 Unauthorized
  • 404 Not Found
  1. Check the retry field first — if present, use the specified delay
  2. For HTTP, check the Retry-After header
  3. Check kind — only retry transient errors:
    • RESOURCE_EXHAUSTED (rate limiting)
    • DEADLINE_EXCEEDED (timeout)
    • UNAVAILABLE (service unavailable)
if error.retry.after:
wait(error.retry.after)
retry()
elif error.kind in [RESOURCE_EXHAUSTED, DEADLINE_EXCEEDED, UNAVAILABLE]:
wait(exponential_backoff())
retry()
else:
fail_permanently()

All other error kinds (13 of 16) should not be retried:

  • CANCELLED — client-initiated cancellation
  • INVALID_ARGUMENT, OUT_OF_RANGE, FAILED_PRECONDITION — fix the request
  • UNAUTHENTICATED — re-authenticate
  • PERMISSION_DENIED — request access
  • NOT_FOUND — resource doesn’t exist
  • ALREADY_EXISTS, CONFLICT — resolve the conflict
  • UNIMPLEMENTED — feature not available
  • INTERNAL, DATA_LOSS, UNKNOWN — contact support

When logging errors, include these fields so you can trace failures across systems:

Error fieldLog keyPurpose
iderror_idMatch with server logs and support tickets
codeerror_codeAggregate errors by type
kinderror_kindAggregate by category
correlationcorrelation_idTrace across services
trace_idtrace_idJump to the distributed trace
{
"level": "ERROR",
"message": "Request failed",
"error_id": "550e8400-e29b-41d4-a716-446655440000",
"error_code": "DIRECTORY_BUSY",
"error_kind": "UNAVAILABLE",
"correlation_id": "req-12345",
"trace_id": "0af7651916cd43dd8448eb211c80319c"
}