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 guidance
Section titled “Retry guidance”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
When to retry
Section titled “When to retry”- Check the
retryfield first — if present, use the specified delay - For HTTP, check the
Retry-Afterheader - Check
kind— only retry transient errors:RESOURCE_EXHAUSTED(rate limiting)DEADLINE_EXCEEDED(timeout)UNAVAILABLE(service unavailable)
Retry strategy
Section titled “Retry strategy”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()Do not retry
Section titled “Do not retry”All other error kinds (13 of 16) should not be retried:
CANCELLED— client-initiated cancellationINVALID_ARGUMENT,OUT_OF_RANGE,FAILED_PRECONDITION— fix the requestUNAUTHENTICATED— re-authenticatePERMISSION_DENIED— request accessNOT_FOUND— resource doesn’t existALREADY_EXISTS,CONFLICT— resolve the conflictUNIMPLEMENTED— feature not availableINTERNAL,DATA_LOSS,UNKNOWN— contact support
Correlating errors
Section titled “Correlating errors”When logging errors, include these fields so you can trace failures across systems:
| Error field | Log key | Purpose |
|---|---|---|
id | error_id | Match with server logs and support tickets |
code | error_code | Aggregate errors by type |
kind | error_kind | Aggregate by category |
correlation | correlation_id | Trace across services |
trace_id | trace_id | Jump 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"}