Errors

This chapter provides an overview of the Google APIs error model as well as general guidance to developers on how to properly generate and handle errors.

Google APIs use a simple protocol-agnostic error model, which allows us to expose a consistent experience across different APIs, API protocols such as gRPC or HTTP, and error contexts (for instance, asynchronous, batch, or workflow errors).

Error Model

The error model is logically defined by google.rpc.Status, an instance of which is returned to the client when an API error occurs. The following code snippet shows the overall design of the error model:

package google.rpc;

message Status {
  // A simple error code that can be easily handled by the client. The
  // actual error code is defined by `google.rpc.Code`.
  int32 code = 1;

  // A developer-facing human-readable error message in English. It should
  // both explain the error and offer an actionable resolution to it.
  string message = 2;

  // Additional error information that the client code can use to handle
  // the error, such as retry delay or a help link.
  repeated google.protobuf.Any details = 3;
}

Because most Google APIs use resource-oriented API design, the error handling follows the same design principle by using a small set of standard errors with a large number of resources. For example, instead of defining different kinds of "not found" errors, the server uses one standard google.rpc.Code.NOT_FOUND error code and tells the client which specific resource was not found. The smaller state space reduces the complexity of documentation, affords better idiomatic mappings in client libraries, and reduces client logic complexity while not restricting the inclusion of actionable information.

Error Codes

Google APIs must use the canonical error codes defined by google.rpc.Code. Individual APIs should avoid defining additional error codes, since developers are very unlikely to write logic to handle a large number of error codes. For reference, handling an average of 3 error codes per API call would mean most application logic would just be for error handling, which would not be a good developer experience.

Error Messages

The error message should help users understand and resolve the API error easily and quickly. In general, consider the following guidelines when writing error messages:

  • Do not assume the user is an expert user of your API. Users could be client developers, operations people, IT staff, or end-users of apps.
  • Do not assume the user knows anything about your service implementation or is familiar with the context of the errors (such as log analysis).
  • When possible, error messages should be constructed such that a technical user (but not necessarily a developer of your API) can respond to the error and correct it.
  • Keep the error message brief. If needed, provide a link where a confused reader can ask questions, give feedback, or get more information that doesn't cleanly fit in an error message. Otherwise, use the details field to expand.

Error Details

Google APIs define a set of standard error payloads for error details, which you can find in google/rpc/error_details.proto. These cover the most common needs for API errors, such as quota failure and invalid parameters. Like error codes, error details should use these standard payloads whenever possible.

Additional error detail types should only be introduced if they can assist application code to handle the errors. If the error information can only be handled by humans, rely on the error message content and let developers handle it manually rather than introducing new error detail types. Note that if additional error detail types are introduced, they must be explicitly registered.

Here are some example error_details payloads:

  • RetryInfo Describes when clients can retry a failed request, may be returned on Code.UNAVAILABLE or Code.ABORTED
  • QuotaFailure Describes how a quota check failed, may be returned on Code.RESOURCE_EXHAUSTED
  • BadRequest Describes violations in a client request, may be returned on Code.INVALID_ARGUMENT

HTTP Mapping

While proto3 messages have native JSON encoding, Google's API Platform uses the following JSON representation for direct HTTP-JSON error responses to allow for backward compatibility:

{
  "error": {
    "code": 401,
    "message": "Request had invalid credentials.",
    "status": "UNAUTHENTICATED",
    "details": [{
      "@type": "type.googleapis.com/google.rpc.RetryInfo",
      ...
    }]
  }
}
Field Description
error The extra layer is for backward compatibility with Google API client library. It also makes the JSON representation more readable to humans.
code The HTTP status code mapping for Status.code
message This corresponds to Status.message
status This corresponds to Status.code
details This corresponds to Status.details

RPC Mapping

Different RPC protocols map the error model differently. For gRPC, the error model is natively supported by the generated code and the runtime library in each supported language. You can find out more in gRPC's API documentation (for example, see gRPC Java's io.grpc.Status).

Client Library Mapping

Google client libraries may choose to surface errors differently per language to be consistent with established idioms. For example, the google-cloud-go library will return an error that implements the same interface as google.rpc.Status, while google-cloud-java will raise an Exception.

Error Localization

The message field in google.rpc.Status is developer-facing and must be in English.

If a user-facing error message is needed, use google.rpc.LocalizedMessage as your details field. While the message field in google.rpc.LocalizedMessage can be localized, ensure that the message field in google.rpc.Status is in English.

By default, the API service should use the authenticated user’s locale or HTTP Accept-Language header to determine the language for the localization.

Handling Errors

Below is a table containing all of the gRPC error codes defined in google.rpc.Code and a short description of their cause. To handle an error, you can check the description for the returned status code and modify your call accordingly.

HTTP RPC Description
200 OK No error.
400 INVALID_ARGUMENT Client specified an invalid argument. Check error message and error details for more information.
400 FAILED_PRECONDITION Request can not be executed in the current system state, such as deleting a non-empty directory.
400 OUT_OF_RANGE Client specified an invalid range.
401 UNAUTHENTICATED Request not authenticated due to missing, invalid, or expired OAuth token.
403 PERMISSION_DENIED Client does not have sufficient permission. This can happen because the OAuth token does not have the right scopes, the client doesn't have permission, or the API has not been enabled for the client project.
404 NOT_FOUND A specified resource is not found, or the request is rejected by undisclosed reasons, such as whitelisting.
409 ABORTED Concurrency conflict, such as read-modify-write conflict.
409 ALREADY_EXISTS The resource that a client tried to create already exists.
429 RESOURCE_EXHAUSTED Either out of resource quota or reaching rate limiting. The client should look for google.rpc.QuotaFailure error detail for more information.
499 CANCELLED Request cancelled by the client.
500 DATA_LOSS Unrecoverable data loss or data corruption. The client should report the error to the user.
500 UNKNOWN Unknown server error. Typically a server bug.
500 INTERNAL Internal server error. Typically a server bug.
501 NOT_IMPLEMENTED API method not implemented by the server.
503 UNAVAILABLE Service unavailable. Typically the server is down.
504 DEADLINE_EXCEEDED Request deadline exceeded. If it happens repeatedly, consider reducing the request complexity.

Error Retries

Clients should retry on 500, 503, and 504 errors with exponential backoff. The minimum delay should be 1s unless it is documented otherwise. For 429 errors, the client may retry with minimum 30s delay. For all other errors, retry may not be applicable - first ensure your request is idempotent, and see the error message for guidance.

Error Propagation

If your API service depends on other services, you should not blindly propagate errors from those services to your clients. When translating errors, we suggest the following:

  • Hide implementation details and confidential information.
  • Adjust the party responsible for the error. For example, a server that receives an INVALID_ARGUMENT error from another service should propagate an INTERNAL to its own caller.

Generating Errors

If you are a server developer, you should generate errors with enough information to help client developers understand and address the problem. At the same time, you must be aware of the security and privacy of the user data, and avoid disclosing sensitive information in the error message and error details, since errors are often logged and may be accessible by others. For example, an error message like "Client IP address is not on whitelist 128.0.0.0/8" exposes information about the server-side policy, which may not be accessible to the user.

To generate proper errors, you first need to be familiar with google.rpc.Code to choose the most suitable error code for each error condition. A server application may check multiple error conditions in parallel, and return the first one.

The following table lists each error code and an example of a good error message.

HTTP RPC Example Error Message
400 INVALID_ARGUMENT Request field x.y.z is xxx, expected one of [yyy, zzz].
400 FAILED_PRECONDITION Resource xxx is a non-empty directory, so it cannot be deleted.
400 OUT_OF_RANGE Parameter 'age' is out of range [0, 125].
401 UNAUTHENTICATED Invalid authentication credentials.
403 PERMISSION_DENIED Permission 'xxx' denied on file 'yyy'.
404 NOT_FOUND Resource 'xxx' not found.
409 ABORTED Couldn’t acquire lock on resource ‘xxx’.
409 ALREADY_EXISTS Resource 'xxx' already exists.
429 RESOURCE_EXHAUSTED Quota limit 'xxx' exceeded.
499 CANCELLED Request cancelled by the client.
500 DATA_LOSS See note.
500 UNKNOWN See note.
500 INTERNAL See note.
501 NOT_IMPLEMENTED Method 'xxx' not implemented.
503 UNAVAILABLE See note.
504 DEADLINE_EXCEEDED See note.

NOTE: Since the client cannot fix the server error, it is not useful to generate additional error details. To avoid leaking sensitive information under error conditions, it is recommended not to generate any error message and only generate google.rpc.DebugInfo error details. The DebugInfo is specially designed only for server-side logging, and must not be sent to client.

The google.rpc package defines a set of standard error payloads, which are preferred to custom error payloads. The following table lists each error code and its matching standard error payload, if applicable.

HTTP RPC Recommended Error Detail
400 INVALID_ARGUMENT google.rpc.BadRequest
400 FAILED_PRECONDITION google.rpc.PreconditionFailure
400 OUT_OF_RANGE google.rpc.BadRequest
401 UNAUTHENTICATED
403 PERMISSION_DENIED
404 NOT_FOUND google.rpc.ResourceInfo
409 ABORTED
409 ALREADY_EXISTS google.rpc.ResourceInfo
429 RESOURCE_EXHAUSTED google.rpc.QuotaFailure
499 CANCELLED
500 DATA_LOSS
500 UNKNOWN
500 INTERNAL
501 NOT_IMPLEMENTED
503 UNAVAILABLE
504 DEADLINE_EXCEEDED

Send feedback about...