Overview
This RFC proposes a standardized approach for handling and representing HTTP wire errors in a consistent and structured manner. The goal is to provide clear and detailed error responses that can be easily understood and processed by clients.
Error Response Structure
Each error response will follow a standardized JSON structure with the following fields:
-
id
: A unique identifier for the error instance. -
http_error_code
: An object containing:-
canonical_name
: A string representing the canonical name of the error. -
status
: An integer representing the HTTP status code.
-
-
message
: A short, human-readable summary of the error. -
detail
: A human-readable explanation specific to this occurrence of the error. -
data
(optional): Additional data related to the error. -
validation
(optional): An array of validation errors, each containing:-
field
: The name of the field that caused the validation error. -
value
: The invalid value provided. -
reason
: A human-readable explanation of why the value is invalid.
-
Example
{
"id": "unique-error-id",
"http_error_code": {
"canonical_name": "ERROR_NAME",
"status": 400
},
"message": "short summary of the error",
"detail": "detailed explanation of the error",
"data": {
"additional": "context-specific data"
},
"validation": [
{
"field": "field_name",
"value": "invalid_value",
"reason": "explanation of why the value is invalid"
}
]
}
Canonical Error Names
The following canonical error names are defined:
-
INVALID_ARGUMENT
: Indicates that the client provided an invalid argument. -
FAILED_PRECONDITION
: Indicates that the operation was rejected because the system is not in a state required for the operation's execution. -
OUT_OF_RANGE
: Indicates that an operation was attempted past the valid range. -
UNSUPPORTED_MEDIA_TYPE
: Indicates that the request entity has a media type which the server or resource does not support. -
DEADLINE_EXCEEDED
: Indicates that the deadline expired before the operation could complete. -
NOT_FOUND
: Indicates that the requested resource could not be found. -
METHOD_NOT_ALLOWED
: Indicates that the HTTP method used is not supported by the resource. -
ALREADY_EXISTS
: Indicates that the resource that a client tried to create already exists. -
ABORTED
: Indicates that the operation was aborted, typically due to a concurrency issue. -
PERMISSION_DENIED
: Indicates that the caller does not have permission to execute the specified operation. -
UNAUTHENTICATED
: Indicates that the request does not have valid authentication credentials for the operation. -
RESOURCE_EXHAUSTED
: Indicates that some resource has been exhausted, perhaps a per-user quota, or perhaps the entire file system is out of space. -
TOO_LARGE
: Indicates that the request entity is larger than limits defined by server. -
UNIMPLEMENTED
: Indicates that the operation is not implemented or not supported/enabled in this service. -
UNAVAILABLE
: Indicates that the service is currently unavailable. -
INTERNAL
: Indicates an internal server error. -
DATA_LOSS
: Indicates unrecoverable data loss or corruption. -
UNKNOWN
: Indicates an unknown error. -
PAYMENT_REQUIRED
: Indicates that payment is required to access the resource. -
NOT_ACCEPTABLE
: Indicates that the resource is not capable of generating content acceptable according to the Accept headers sent in the request. -
PROXY_AUTH_REQUIRED
: Indicates that the client must first authenticate itself with the proxy. -
REQUEST_TIMEOUT
: Indicates that the server timed out waiting for the request. -
GONE
: Indicates that the resource requested is no longer available and will not be available again. -
LENGTH_REQUIRED
: Indicates that the request did not specify the length of its content, which is required by the requested resource. -
PRECONDITION_FAILED
: Indicates that the server does not meet one of the preconditions that the requester put on the request. -
REQUEST_URI_TOO_LONG
: Indicates that the URI provided was too long for the server to process. -
REQUESTED_RANGE_NOT_SATISFIABLE
: Indicates that the server cannot supply the portion of the file requested. -
EXPECTATION_FAILED
: Indicates that the server cannot meet the requirements of the Expect request-header field. -
IM_A_TEAPOT
: Indicates that the server refuses to brew coffee because it is, permanently, a teapot. -
MISDIRECTED_REQUEST
: Indicates that the request was directed at a server that is not able to produce a response. -
UNPROCESSABLE_ENTITY
: Indicates that the server understands the content type of the request entity, but was unable to process the contained instructions. -
LOCKED
: Indicates that the resource that is being accessed is locked. -
FAILED_DEPENDENCY
: Indicates that the request failed due to failure of a previous request. -
TOO_EARLY
: Indicates that the server is unwilling to risk processing a request that might be replayed. -
UPGRADE_REQUIRED
: Indicates that the client should switch to a different protocol. -
PRECONDITION_REQUIRED
: Indicates that the origin server requires the request to be conditional. -
REQUEST_HEADER_FIELDS_TOO_LARGE
: Indicates that the server is unwilling to process the request because its header fields are too large. -
UNAVAILABLE_FOR_LEGAL_REASONS
: Indicates that the resource is unavailable for legal reasons. -
HTTP_VERSION_NOT_SUPPORTED
: Indicates that the server does not support the HTTP protocol version used in the request. -
VARIANT_ALSO_NEGOTIATES
: Indicates that the server has an internal configuration error. -
INSUFFICIENT_STORAGE
: Indicates that the server is unable to store the representation needed to complete the request. -
LOOP_DETECTED
: Indicates that the server detected an infinite loop while processing a request. -
NOT_EXTENDED
: Indicates that further extensions to the request are required for the server to fulfill it. -
NETWORK_AUTHENTICATION_REQUIRED
: Indicates that the client needs to authenticate to gain network access. -
PAGE_EXPIRED
: Indicates that the page has expired. -
BLOCKED_BY_WINDOWS_PARENTAL_CONTROLS
: Indicates that the request was blocked by Windows Parental Controls. -
INVALID_TOKEN
: Indicates that the token provided is invalid. -
TOKEN_REQUIRED
: Indicates that a token is required to access the resource. -
BANDWIDTH_LIMIT_EXCEEDED
: Indicates that the bandwidth limit has been exceeded. -
INVALID_SSL_CERTIFICATE
: Indicates that the SSL certificate is invalid. -
SITE_OVERLOADED
: Indicates that the site is overloaded. -
SITE_FROZEN
: Indicates that the site is frozen. -
NETWORK_READ_TIMEOUT
: Indicates that there was a network read timeout error.
Error Handling
Invalid Argument
When the client provides an invalid argument, the server should respond with an INVALID_ARGUMENT
error.
Example
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"http_error_code": {
"canonical_name": "INVALID_ARGUMENT",
"status": 400
},
"message": "invalid account number provided",
"detail": "the account number '123456789' does not exist in our records"
}
Failed Precondition
When the operation is rejected due to a failed precondition, the server should respond with a FAILED_PRECONDITION
error.
Example
{
"id": "b2c3d4e5-f6a7-8901-bcde-f23456789012",
"http_error_code": {
"canonical_name": "FAILED_PRECONDITION",
"status": 400
},
"message": "insufficient funds",
"detail": "the account '987654321' has insufficient funds for the transaction",
"data": {
"current_balance": 50.00,
"required_balance": 100.00
}
}
Unauthenticated
When the request lacks valid authentication credentials, the server should respond with an UNAUTHENTICATED
error.
Example
{
"id": "c3d4e5f6-a7b8-9012-cdef-345678901234",
"http_error_code": {
"canonical_name": "UNAUTHENTICATED",
"status": 401
},
"message": "unauthorized access",
"detail": "the provided credentials are invalid"
}
Unauthorized Access
Due to invalid JWK.
{
"id": "b445b036-fd2e-4583-b4cc-61c2b8fb0b73",
"http_error_code": {
"canonical_name": "UNAUTHENTICATED",
"status": 401
},
"message": "auth: verify: jwt: unknown kid"
}
Permission Denied
When the caller does not have permission to execute the specified operation, the server should respond with a PERMISSION_DENIED
error.
Example
{
"id": "d4e5f6a7-b8c9-0123-def4-567890123456",
"http_error_code": {
"canonical_name": "PERMISSION_DENIED",
"status": 403
},
"message": "account locked",
"detail": "the account '123456789' is locked due to multiple failed login attempts",
"data": {
"lock_duration": "24 hours"
}
}
Not Found
When the requested resource is not found, the server should respond with a NOT_FOUND
error.
Example
{
"id": "e5f6a7b8-c9d0-1234-ef56-789012345678",
"http_error_code": {
"canonical_name": "NOT_FOUND",
"status": 404
},
"message": "transaction not found",
"detail": "the transaction with id 'tx1234567890' was not found"
}
Validation Error
When the request contains invalid fields, the server should respond with an INVALID_ARGUMENT
error and include validation details.
Example
{
"id": "c30adf71-25c0-4a2b-a1f2-c3ee17efcd17",
"http_error_code": {
"canonical_name": "INVALID_ARGUMENT",
"status": 400
},
"message": "validation failure",
"detail": "fields were invalid",
"validation": [
{
"field": "name",
"value": "jo",
"reason": "name must be at least 3 characters long"
},
{
"field": "email",
"value": "invalid@comcom",
"reason": "email must be a valid email address"
}
]
}
Internal Server Error
When an unexpected error occurs while processing the request, the server should respond with an INTERNAL
error.
{
"id": "f6a7b8c9-d0e1-2345-f678-901234567890",
"http_error_code": {
"canonical_name": "INTERNAL",
"status": 500
},
"message": "server error",
"detail": "an unexpected error occurred while processing the request"
}
Complex Error with Nested Data
When an error involves multiple nested errors, the server should provide detailed context for each part of the error message.
Example
{
"id": "9f8b7c6d-4e5f-4a2b-8c3d-1e2f3a4b5c6d",
"http_error_code": {
"canonical_name": "FAILED_PRECONDITION",
"status": 400
},
"message": "transaction failed: insufficient funds: daily withdrawal limit exceeded",
"data": [
{
"message": "transaction failed",
"data": {
"transaction_id": "tx1234567890",
"amount": 150.00,
"currency": "USD"
}
},
{
"message": "insufficient funds",
"data": {
"account_id": "acc987654321",
"current_balance": 50.00,
"required_balance": 150.00
}
},
{
"message": "daily withdrawal limit exceeded",
"data": {
"account_id": "acc987654321",
"daily_limit": 1000.00,
"amount_attempted": 1500.00
}
}
]
}
In this example, the error message is composed of three parts:
transaction failed
insufficient funds
daily withdrawal limit exceeded
Each part of the error message has its own section of data, providing detailed context for each part of the error. This structure allows clients to understand the specific context and data related to each part of the error message, making it easier to debug and resolve issues.
Problem Details
The Problem Details RFC is a standardized format for representing errors in HTTP APIs. It defines a structured way to provide detailed information about errors in a machine-readable format, making it easier for clients to understand and handle errors effectively.
Example
{
"status": 400,
"title": "Insufficient Funds",
"detail": "The account '987654321' has insufficient funds for the transaction.",
"type": "https://example.com/probs/insufficient-funds",
"instance": "/accounts/12345/transactions/67890",
"extra_custom_key": "current_balance",
"extra_custom_value": 50.00,
"extra_custom_key2": "required_balance",
"extra_custom_value2": 100.00
}
Differences Between HTTP Wire Errors and Problem Details
While both HTTP Wire Errors and Problem Details provide a structured way to represent errors in HTTP APIs, there are some key differences:
Flexibility: HTTP Wire Errors offer a more flexible structure that can include additional fields such as
id
,http_error_code
,message
,data
, andvalidation
. This allows for more detailed and context-specific error information.Canonical Error Names: HTTP Wire Errors define a set of canonical error names that standardize common error scenarios, making it easier to categorize and handle errors consistently across different parts of an application.
Nested Data: HTTP Wire Errors support nested data structures, allowing for detailed context for each part of a complex error message. This is particularly useful for errors that involve multiple related issues.
Validation Errors: HTTP Wire Errors include a dedicated
validation
field to provide detailed information about validation errors, including the specific fields and reasons for the validation failure.
What Problem Details Were Missing
Problem Details (RFC 7807) provide a standardized format for representing errors, but they lack some features that are addressed by HTTP Wire Errors:
- Canonical Error Names: Problem Details do not define a set of canonical error names, which can lead to inconsistencies in error categorization.
- Nested Data: Problem Details do not natively support nested data structures, making it harder to provide detailed context for complex errors.
- Validation Errors: Problem Details do not have a dedicated field for validation errors, which can make it harder to provide detailed information about validation issues.
How HTTP Wire Errors Provide a Solution
HTTP Wire Errors address these limitations by:
- Defining a set of canonical error names for consistent error categorization.
- Supporting nested data structures to provide detailed context for complex errors.
- Including a dedicated
validation
field for detailed validation error information.
Author
Gerasimos Maropoulos is the author of the Iris web framework, a highly efficient and feature-rich web framework for the Go programming language. He is well-known in the programming community for his contributions to web development and his expertise in the Go language. Gerasimos has authored numerous online articles and tutorials that help developers understand and leverage the power of Go for building scalable and high-performance web applications. His work on Iris has made it one of the most popular web frameworks in the Go ecosystem, known for its simplicity, speed, and extensive feature set.
Gerasimos wrote this RFC to address the need for a standardized approach to handling and representing HTTP wire errors. By providing a clear and consistent structure for error responses, he aims to make it easier for developers to debug and understand the context of errors in their applications. This RFC is part of his ongoing efforts to improve the developer experience and ensure that applications built with Iris are robust and maintainable.
Conclusion
This RFC defines a standardized approach for handling and representing HTTP wire errors. By following this structure, developers can ensure consistent and clear error responses, making it easier for clients to understand and handle errors effectively.
Top comments (0)