This guide explains how the Google Ads API handles and communicates errors.
Understanding the structure and meaning of API errors is crucial for building
robust applications that can gracefully handle issues, from invalid input to
temporary service unavailability.

The Google Ads API follows the standard Google API error model, which is based on
[gRPC Status codes](https://cloud.google.com/apis/design/errors). Each API response that results in an error
includes a `Status` object containing:

- A numeric error code.
- An error message.
- Optional, additional error details.

## Canonical error codes

The Google Ads API uses a set of canonical error codes defined by gRPC and HTTP. These
codes provide a high-level indication of the error type. You should always check
this numeric code first to understand the fundamental nature of the problem.

The following table summarizes the most common codes you might encounter when
using the Google Ads API:

| gRPC code | HTTP code | Enum name | Description | Guidance |
|---|---|---|---|---|
| 0 | 200 | `OK` | No error; indicates success. | N/A |
| 1 | 499 | `CANCELLED` | The operation was cancelled, typically by the client. | Usually means the client stopped waiting. Check client-side timeouts. |
| 2 | 500 | `UNKNOWN` | An unknown error occurred. More details might be in the error message or details. | Treat as a server error. Can often be retried with backoff. |
| 3 | 400 | `INVALID_ARGUMENT` | The client specified an invalid argument. This indicates a problem that prevents the API from processing the request, such as a malformed resource name or invalid value. | Client error: Review your request parameters and ensure they meet API requirements. The error details usually provide information about which argument was invalid and how---use these details to fix the request. Don't retry without fixing the request. |
| 4 | 504 | `DEADLINE_EXCEEDED` | The deadline expired before the operation could complete. | Server error: Often transient. Consider retrying with [exponential backoff](https://developers.google.com/google-ads/api/docs/best-practices/understand-api-errors#retry-strategy). |
| 5 | 404 | `NOT_FOUND` | Some requested entity, such as a campaign or ad group, was not found. | Client error: Verify the existence and ID of the resources you are trying to access. Don't retry without correction. |
| 6 | 409 | `ALREADY_EXISTS` | The entity the client attempted to create already exists. | Client error: Avoid creating duplicate resources. Check if the resource exists before attempting to create it. |
| 7 | 403 | `PERMISSION_DENIED` | The caller does not have permission to execute the specified operation. | Client error: Check [authentication](https://developers.google.com/google-ads/api/docs/oauth/overview), authorization, and user roles for the Google Ads account. Don't retry without resolving permissions. |
| 8 | 429 | `RESOURCE_EXHAUSTED` | Either a resource has been exhausted (for example, you have exceeded your quota), or a system is overloaded. | Client/Server error: Typically requires waiting. Implement [exponential backoff](https://developers.google.com/google-ads/api/docs/best-practices/understand-api-errors#retry-strategy) and potentially reduce request rate. See [API limits and quotas](https://developers.google.com/google-ads/api/docs/best-practices/quotas). |
| 9 | 400 | `FAILED_PRECONDITION` | The operation was rejected because the system is not in a state required for the operation's execution. For example, a required field is missing. | Client error: The request is valid, but the *state* is wrong. Review error details to understand the precondition failure. Don't retry without state correction. |
| 10 | 409 | `ABORTED` | The operation was aborted, typically due to a concurrency issue like a transaction conflict. | Server error: Often safe to retry with a short backoff. |
| 11 | 400 | `OUT_OF_RANGE` | The operation was attempted past the valid range. | Client error: Correct the range or index. |
| 12 | 501 | `UNIMPLEMENTED` | The operation is not implemented or not supported by the API. | Client error: Check API version and available features. Don't retry. |
| 13 | 500 | `INTERNAL` | An internal error occurred. This is a general catch-all for server-side issues. | Server error: Can generally be retried with [exponential backoff](https://developers.google.com/google-ads/api/docs/best-practices/understand-api-errors#retry-strategy). If persistent, [report the issue](https://developers.google.com/google-ads/api/support). |
| 14 | 503 | `UNAVAILABLE` | The service is temporarily unavailable. This is most likely a transient condition. | Server error: Highly recommended to retry with [exponential backoff](https://developers.google.com/google-ads/api/docs/best-practices/understand-api-errors#retry-strategy). |
| 15 | 500 | `DATA_LOSS` | Unrecoverable data loss or corruption. | Server error: Rare. Indicates a serious problem. Don't retry. If persistent, [report the issue](https://developers.google.com/google-ads/api/support). |
| 16 | 401 | `UNAUTHENTICATED` | The request does not have valid authentication credentials. | Client error: Verify your [authentication tokens](https://developers.google.com/google-ads/api/docs/oauth/overview) and credentials. Don't retry without fixing authentication. |

For more details on these codes, refer to [API Design Guide - Error
codes](https://cloud.google.com/apis/design/errors).

## Understand error details

Beyond the top-level code, the Google Ads API provides more specific error information
within the `details` field of the `Status` object. This field often contains a
[`GoogleAdsFailure`](https://developers.google.com/google-ads/api/reference/rpc/v26/GoogleAdsFailure) proto, which includes a list of
individual [`GoogleAdsError`](https://developers.google.com/google-ads/api/reference/rpc/v26/GoogleAdsError) objects.

Each [`GoogleAdsFailure`](https://developers.google.com/google-ads/api/reference/rpc/v26/GoogleAdsFailure) object contains:

- `errors`: A list of [`GoogleAdsError`](https://developers.google.com/google-ads/api/reference/rpc/v26/GoogleAdsError) objects, each detailing a specific error that occurred.
- `request_id`: A unique ID for the request, useful for debugging and support purposes.

Each [`GoogleAdsError`](https://developers.google.com/google-ads/api/reference/rpc/v26/GoogleAdsError) object provides:

- [`error_code`](https://developers.google.com/google-ads/api/reference/rpc/v26/GoogleAdsError#error_code): A more granular, [Google Ads API-specific
  `ErrorCode`](https://developers.google.com/google-ads/api/reference/rpc/v26/ErrorCode) ([common errors](https://developers.google.com/google-ads/api/docs/common-errors)), such as [`AuthenticationError.NOT_ADS_USER`](https://developers.google.com/google-ads/api/reference/rpc/v26/AuthenticationErrorEnum.AuthenticationError#not_ads_user).
- [`message`](https://developers.google.com/google-ads/api/reference/rpc/v26/GoogleAdsError#message): A human-readable description of the specific error.
- [`trigger`](https://developers.google.com/google-ads/api/reference/rpc/v26/GoogleAdsError#trigger): The [`Value`](https://developers.google.com/google-ads/api/reference/rpc/v26/Value) that caused the error, if applicable.
- [`location`](https://developers.google.com/google-ads/api/reference/rpc/v26/GoogleAdsError#location): An [`ErrorLocation`](https://developers.google.com/google-ads/api/reference/rpc/v26/ErrorLocation) describing where in the request the error occurred, including field paths.
- [`details`](https://developers.google.com/google-ads/api/reference/rpc/v26/GoogleAdsError#details): Additional [`ErrorDetails`](https://developers.google.com/google-ads/api/reference/rpc/v26/ErrorDetails), such as unpublished error reasons.

### Example of error details

When you receive an error, your [client library](https://developers.google.com/google-ads/api/docs/client-libs) will allow you to
access these details. For example, an `INVALID_ARGUMENT` (Code 3) might have
`GoogleAdsFailure` details like this:

    {
      "code": 3,
      "message": "The request was invalid.",
      "details": [
        {
          "@type": "type.googleapis.com/google.ads.googleads.v26.errors.GoogleAdsFailure",
          "errors": [
            {
              "errorCode": {
                "fieldError": "REQUIRED"
              },
              "message": "The required field was not present.",
              "location": {
                "fieldPathElements": [
                  { "fieldName": "operations", "index": 0 },
                  { "fieldName": "create" },
                  { "fieldName": "name" }
                ]
              }
            },
            {
              "errorCode": {
                "stringLengthError": "TOO_SHORT"
              },
              "message": "The provided string is too short.",
              "trigger": {
                "stringValue": ""
              },
              "location": {
                "fieldPathElements": [
                  { "fieldName": "operations", "index": 0 },
                  { "fieldName": "create" },
                  { "fieldName": "description" }
                ]
              }
            }
          ],
          "requestId": "AbCdEfGhIjKlMnOpQrStUv"
        }
      ]
    }

In this example, despite the top-level `INVALID_ARGUMENT`, the
[`GoogleAdsFailure`](https://developers.google.com/google-ads/api/reference/rpc/v26/GoogleAdsFailure) details tell you that the `name` and
`description` fields caused the issue and why ([`REQUIRED`](https://developers.google.com/google-ads/api/reference/rpc/v26/FieldErrorEnum.FieldError#required) and
[`TOO_SHORT`](https://developers.google.com/google-ads/api/reference/rpc/v26/StringLengthErrorEnum.StringLengthError#too_short), respectively).

## Locate error details

How you access error details depends on whether you are using standard API
calls, partial failure, or streaming.

### Standard and streaming API calls

When an API call fails without using partial failure, including [streaming
calls](https://developers.google.com/google-ads/api/docs/reporting/streaming), the [`GoogleAdsFailure`](https://developers.google.com/google-ads/api/reference/rpc/v26/GoogleAdsFailure) object is
returned as part of the trailing metadata in the gRPC response headers. If
you're using REST for standard calls, [`GoogleAdsFailure`](https://developers.google.com/google-ads/api/reference/rpc/v26/GoogleAdsFailure)
is returned in the HTTP response. [Client libraries](https://developers.google.com/google-ads/api/docs/client-libs) typically
surface this as an exception with a [`GoogleAdsFailure`](https://developers.google.com/google-ads/api/reference/rpc/v26/GoogleAdsFailure)
attribute.

### Partial failure

If you are using [partial failure](https://developers.google.com/google-ads/api/docs/best-practices/partial-failures), errors for failed
operations are returned in the `partial_failure_error` field of the response,
not in the response headers. In this case, the
[`GoogleAdsFailure`](https://developers.google.com/google-ads/api/reference/rpc/v26/GoogleAdsFailure) is embedded within a
`google.rpc.Status` object in the response.

### Batch jobs

For [batch processing](https://developers.google.com/google-ads/api/docs/batch-processing/overview), errors for individual operations can
be found by calling [`BatchJobService.ListBatchJobResults`](https://developers.google.com/google-ads/api/reference/rpc/v26/BatchJobService/ListBatchJobResults)
after the job is complete. Each operation result will include a `status` field
containing error details if the operation failed.

## Request ID

The `request-id` is a unique string that identifies your API request and is
essential for troubleshooting.

You can find the `request-id` in multiple places:

- `GoogleAdsFailure`: If an API call fails and [`GoogleAdsFailure`](https://developers.google.com/google-ads/api/reference/rpc/v26/GoogleAdsFailure) is returned, it will contain a `request_id`.
- **Trailing metadata:** For both successful and failed requests, `request-id` is available in the trailing metadata of the gRPC response.
- **Response headers:** For both successful and failed requests, `request-id` is also available in the gRPC and HTTP response headers, with the exception of successful streaming requests.
- `SearchGoogleAdsStreamResponse`: For streaming requests, each [`SearchGoogleAdsStreamResponse`](https://developers.google.com/google-ads/api/reference/rpc/v26/SearchGoogleAdsStreamResponse) message contains a `request_id` field.

When logging errors or contacting support, make sure to include the
`request-id` to help with diagnosing issues.

## Best practices for error handling

To build resilient applications, implement the following best practices:

1. **Inspect error details:** Always parse the `details` field of the `Status`
   object, specifically looking for [`GoogleAdsFailure`](https://developers.google.com/google-ads/api/reference/rpc/v26/GoogleAdsFailure).
   The granular `error_code`, `message`, and `location` within
   [`GoogleAdsError`](https://developers.google.com/google-ads/api/reference/rpc/v26/GoogleAdsError) provide the most actionable information
   for debugging and user feedback.

2. **Differentiate client from server errors:**

   - **Client errors:** Codes like `INVALID_ARGUMENT`, `NOT_FOUND`, `PERMISSION_DENIED`, `FAILED_PRECONDITION`, `UNAUTHENTICATED`. These require changes to the request or your application's state/credentials. Don't retry the request without addressing the issue.
   - **Server errors:** Codes like `UNAVAILABLE`, `INTERNAL`, `DEADLINE_EXCEEDED`, `UNKNOWN`. These suggest a temporary issue with the API service.
3. **Implement a retry strategy:**

   - **When to retry:** Retry *only* for transient server errors such as `UNAVAILABLE`, `DEADLINE_EXCEEDED`, `INTERNAL`, `UNKNOWN`, and `ABORTED`.
   - **Exponential backoff:** Use an exponential backoff algorithm to wait for increasing periods between retries. This helps avoid overwhelming an already stressed service. For example, wait 1s, then 2s, then 4s, continuing up to a maximum number of retries or total wait time.
   - **Jitter:** Add a small random amount of "jitter" to the backoff delays to prevent the "thundering herd" problem where many clients retry simultaneously.
4. **Log thoroughly:** Log the full error response, including all details,
   especially the request ID. This information is essential for debugging and
   for reporting issues to Google support if needed.

5. **Provide user feedback:** Based on the specific
   [`GoogleAdsError`](https://developers.google.com/google-ads/api/reference/rpc/v26/GoogleAdsError) codes and messages, provide clear and
   helpful feedback to your application's users. For example, instead of just
   "An error occurred," you can say "Campaign name is required" or "The
   provided ad group ID was not found."

By following these guidelines, you can effectively diagnose and handle errors
returned by the Google Ads API, leading to more stable and user-friendly applications.