We've categorized errors into the following broad categories:

- Authentication
- Errors that can be retried
- Validation
- Sync-related

Though these categories don't encompass all possible errors, and some may fit
into more than one category, they can nevertheless serve as a starting point for
structuring your app's error handling. See the following resources for more
details about specific errors:

- [Common errors](https://developers.google.com/google-ads/api/docs/common-errors) provides more details about a particular error.
- [`google.rpc.Status`](https://developers.google.com/google-ads/api/reference/rpc/google.rpc#google.rpc.Status) provides details about the logical error model used by the API.
- [Canonical error codes](https://developers.google.com/google-ads/api/docs/best-practices/understand-api-errors) provides a list and explanation of canonical error codes defined by gRPC and HTTP in the context of the Google Ads API.

## Authentication errors

Authentication refers to whether your app has been given permission by a user to
access Google Ads on their behalf. Authentication is managed through credentials
generated by the [OAuth2 flow](https://developers.google.com/google-ads/api/docs/oauth/overview).

The most common reason an authentication error arises from factors beyond your
control is that the authenticated user has revoked the permission they gave your
app to act on their behalf. For example, if your app manages separate Google Ads
accounts for independent clients and authenticates separately as each client
when managing that client's account, a client could revoke your app's access at
any time. Depending on when your access was revoked, the API may directly return
an [`AuthenticationError.OAUTH_TOKEN_REVOKED`](https://developers.google.com/google-ads/api/reference/rpc/v26/AuthenticationErrorEnum.AuthenticationError#oauth_token_revoked) error, or
the built-in credential objects in the [client libraries](https://developers.google.com/google-ads/api/docs/client-libs) may throw
a token revoked exception. In either case, if your app has a UI for your
clients, it could ask them to relaunch the OAuth2 flow to reestablish your app's
permission to act on their behalf.

Relatedly, if your Google Cloud project only has the [Test access
level](https://developers.google.com/google-ads/api/docs/api-policy/access-levels) and attempts to make requests against a production
(non-test) account, the API returns an
[`AuthorizationError`](https://developers.google.com/google-ads/api/reference/rpc/v26/AuthorizationErrorEnum.AuthorizationError) whose enum value depends on the API
version:

- **Starting in `v25`:** Returns [`AuthorizationError.CLOUD_PROJECT_NOT_APPROVED_FOR_PRODUCTION`](https://developers.google.com/google-ads/api/reference/rpc/v26/AuthorizationErrorEnum.AuthorizationError#cloud_project_not_approved_for_production).
- **`v24` and earlier:** Returns [`AuthorizationError.ACTION_NOT_PERMITTED`](https://developers.google.com/google-ads/api/reference/rpc/v26/AuthorizationErrorEnum.AuthorizationError#action_not_permitted).

## Errors that can be retried

Some errors, such as [`TRANSIENT_ERROR`](https://developers.google.com/google-ads/api/reference/rpc/v26/InternalErrorEnum.InternalError#transient_error) or
[`INTERNAL_ERROR`](https://developers.google.com/google-ads/api/reference/rpc/v26/InternalErrorEnum.InternalError#internal_error), can indicate a temporary problem that may be
resolved by retrying the request after a short pause.

For user-initiated requests, one strategy is to immediately indicate an error in
your UI and give the user an option to trigger a retry. Alternatively, your app
could first automatically retry the request, only exposing the error in the UI
after reaching a maximum number of retries or total user wait time.

For requests initiated on the backend, your app should automatically retry the
request up to a maximum number of retries.

When you retry requests, use an exponential backoff policy with randomized
jitter. For example, if you first pause 5 seconds before the first retry, you
could pause 10 seconds after the second and 20 seconds after the third retry,
adding a small random delay to each interval to prevent synchronized retry
spikes. Exponential backoff helps ensure you are not calling the API too
aggressively. If an error persists after exhausting retries, log the
[`request-id`](https://developers.google.com/google-ads/api/docs/best-practices/understand-api-errors#request-id) from the response for troubleshooting.

## Validation errors

Validation errors indicate that an input to an operation was not acceptable.
Examples include [`PolicyViolationError`](https://developers.google.com/google-ads/api/reference/rpc/v26/PolicyViolationErrorEnum.PolicyViolationError),
[`DateError`](https://developers.google.com/google-ads/api/reference/rpc/v26/DateErrorEnum.DateError), [`DateRangeError`](https://developers.google.com/google-ads/api/reference/rpc/v26/DateRangeErrorEnum.DateRangeError),
[`StringLengthError`](https://developers.google.com/google-ads/api/reference/rpc/v26/StringLengthErrorEnum.StringLengthError), and
[`UrlFieldError`](https://developers.google.com/google-ads/api/reference/rpc/v26/UrlFieldErrorEnum.UrlFieldError).

> [!NOTE]
> **Note:** Starting June 1, 2026, granular date segmentation (daily, hourly, and weekly) is limited to a 37-month lookback window. Queries requesting granular date segments older than 37 months return [`DateRangeError.REQUESTED_DATE_GRANULARITY_NOT_SUPPORTED`](https://developers.google.com/google-ads/api/reference/rpc/v26/DateRangeErrorEnum.DateRangeError#requested_date_granularity_not_supported) (starting in `v24`).

Validation errors occur most commonly in user-initiated requests, where a user
has entered invalid input. In these cases, you should provide an appropriate
error message to the user based on the specific API error you received. You can
also validate user input for common mistakes before making an API call, making
your app more responsive and your API usage more efficient. For requests from
the backend, your app could add the failed operation to a queue for a human
operator to review.

## Sync-related errors

Many Google Ads apps maintain a local database to store their Google Ads
objects. One challenge to this approach is that the local database may go out of
sync with the actual objects in Google Ads. For example, a user might delete an
ad group directly in Google Ads, but the app and local database are unaware of
the change and continue to issue API calls as if the ad group existed. These
sync issues can manifest as a variety of errors such as
[`DUPLICATE_CAMPAIGN_NAME`](https://developers.google.com/google-ads/api/reference/rpc/v26/CampaignErrorEnum.CampaignError#duplicate_campaign_name),
[`DUPLICATE_ADGROUP_NAME`](https://developers.google.com/google-ads/api/reference/rpc/v26/AdGroupErrorEnum.AdGroupError#duplicate_adgroup_name),
[`AD_NOT_UNDER_ADGROUP`](https://developers.google.com/google-ads/api/reference/rpc/v26/AdGroupAdErrorEnum.AdGroupAdError#ad_not_under_adgroup),
[`CANNOT_OPERATE_ON_REMOVED_ADGROUPAD`](https://developers.google.com/google-ads/api/reference/rpc/v26/AdGroupAdErrorEnum.AdGroupAdError#cannot_operate_on_removed_adgroupad),
and many others.

For user-initiated requests, one strategy is to alert the user to a possible
sync problem, immediately launch a job that retrieves the relevant class of
Google Ads objects and updates the local database, then prompt the user to
refresh the UI.

For backend requests, some errors provide enough information for your app to
automatically and incrementally correct your local database. For example,
[`CANNOT_OPERATE_ON_REMOVED_ADGROUPAD`](https://developers.google.com/google-ads/api/reference/rpc/v26/AdGroupAdErrorEnum.AdGroupAdError#cannot_operate_on_removed_adgroupad)
should cause your app to mark that ad as removed in your local database. Errors
that you cannot handle in this way could cause your app to launch a more
complete sync job or be added to a queue for a human operator to review.