Name: Errors
Status: approved
Created: 2023-03-25
Updated: 2023-07-13

Errors (#193)

Errors are a critical part of a consumer's experience when interacting with our APIs. Something isn't working, and it is likely that the user is frustrated. With that in mind, we aim to provide as much information about how to resolve the issue at hand as possible in the error response.

By providing a consistent error format, we allow developers to handle any errors they may receive using common error-handling logic.

Guidance

HTTP APIs at Kong must return errors that adhere to RFC 7807 "Problem Details for HTTP APIs".

The only exception is when there is an infrastructure failure and an application cannot be reached. Third party tools may use their own error format, but should be configured to follow RFC 7807 where possible.

HTTP Content-Type

All error responses must send the application/problem+json content type

Response Body Fields

All error messages must contain the following fields:

Name Required Description Example
type true A unique identifier for this error. When dereferenced it must provide human-readable documentation for the problem. The URL must follow #122 - Resource Names and must not contain URI fragments type https://kongapi.info/konnect/invalid-permissions
status true The HTTP status code of the error. Useful when passing the response body to child properties in a frontend UI. Must be returned as an integer 403
title true A short, human-readable summary of the problem. It should not change between occurences of a problem, except for localization. Should be provided as "Sentence case" for direct use in the UI Invalid Permissions
detail true A human readable explanation specific to this occurence of the problem. This field may contain request/entity data to help the user understand what went wrong. Enclose variable values in square brackets. Should be provided as "Sentence case" for direct use in the UI You must have the [administrator] role to perform this action
instance true Used to return the correlation ID back to the user, in the format kong:trace:<correlation_id>. This helps us find the relevant logs when a customer reports an issue kong:trace:6c1ef33ae5bce33634d7d7d695c7f203

Here's a complete example:

{
"type": "https://kongapi.info/konnect/invalid-permissions",
"status": 403,
"title": "Invalid Permissions",
"detail": "You must have the [administrator] role to perform this action",
"instance": "kong:trace:6c1ef33ae5bce33634d7d7d695c7f203"
}

Extensions

In addition to the fields shown above, the RFC allows for extensions. Any extensions we choose to use MUST be agreed by the editors.

Invalid Parameters

All 400 errors MUST return an invalid_parameters key in the response.

Used to indicate which fields have invalid values when validated. Both a human readable value (reason) and a type that can be used for localised results (rule) must be provided.

All entries in invalid_parameters must provide field, reason and source. source value must be one of : path, body, header, query. rule may be provided as a hint to the consumer to help understand the type of failure. Additional guidance on these fields is given below.

Some rule types may have additional fields e.g. enum also has choices.

The invalid_parameters.reason field may be taken directly from JSON schema validation e.g. unknown field or required field missing.

The invalid_parameters.rule field can be used by the UI to understand what type of error has been returned.

Example:

{
"type": "https://kongapi.info/konnect/create-member-validation",
"status": 400,
"title": "Validation failed",
"instance": "kong:trace:6c1ef33ae5bce33634d7d7d695c7f203",
"invalid_parameters": [
{ "field": "name", "rule": "required", "reason": "is a required field", "source": "body" },
{
"field": "role",
"reason": "must be one of: [admin, member]",
"rule": "enum",
"choices": ["admin", "member"],
"source": "query",
},
{ "field": "ssh_key", "reason": "invalid SSH key provided", "source": "body" }
]
}

Guidance: field

  1. For all query parameters that fail validation, the query parameter name must be the field value, e.g.:
    • GET /v1/services/1234?page=-1 = {"field": "page", ...}
  2. For all request body parameters that fail validation, the field value must be a dot notation path to the failing field. If the failing field is in a list, we must provide the failing index:
    • POST /v1/services, body: {"service": {"unknown_field": 123}} = {"field": "service.unknown_field", ...}
    • POST /v1/services, body: {"service": {"some_array": [{"unknown_field": 123}]}} = {"field": "service.some_array[0]", ...}
    • POST /v1/services, body: unknown_field=123 = {"field": "unknown_field", ...}

For APIs that do not provide field names (e.g. multipart uploads), you may use field: "body" to return errors. It is valid to return multiple entries with the same field (useful for validating against multiple rules).

Guidance: rule

Here are the possible values for rule, and any additional fields that are required when using each rule:

Rule Description Additional Fields
required Property is required. N/A
unique Value must be unique. N/A
dependent_fields Property requires dependent properties to be specified. dependents: A list of dependent properties for this field
enum Value must be one of an enumerated set of values. Must be exclusive of min_*, max_* and is_* rules as enum implies the format of a value. choices: A list of valid values for this field
min_length String must have a minimum number of characters. minimum: Minimum length for this field
max_length String must not exceed a maximum number of characters. maximum: Maximum length for this field
min_items Array must contain at least this many items. minimum: Minimum items for this field
max_items Array must contain at most this many items. maximum: Maximum items for this field
min Numeric field value must be greater than or equal to this value. minimum: Minimum numeric value for this field
max Numeric field value must be less than or equal to this value. maximum: Maximum numeric value for this field
min_digits Value must have a specified number of digits. minimum: Minimum required number of digits
min_lowercase String must have a minimum number of lowercase characters. minimum: Minimum required number of lowercase characters
min_uppercase String must have a minimum number of uppercase characters. minimum: Minimum required number of upper case characters
min_symbols String must have a minimum number of symbols. minimum: Minimum required number of symbols
is_array Value must be an array. N/A
is_boolean true or false. N/A
is_date_time Value must be a string in RFC-3339 date format. N/A
is_integer Value must be a signed integer. N/A
is_null Value must be null. N/A
is_number Value must be a double precision floating point number. N/A
is_object Value must be an object mapping strings to arbitrary types. N/A
is_string Value must be a utf-8 string. N/A
is_uuid Value must be a UUID. N/A
unknown_property Property is not listed in the component definition, and does not allow additional properties. N/A
missing_reference The reference represented by the given value doesn't exist. N/A

Any validation rules may be added by raising a PR to update this file. Consult https://swagger.io/docs/specification/data-models/data-types/ when adding new rules.

Base Error Responses

The following table lists "base" or "standard" errors that should be consistent across Konnect APIs. The base path for error types is "https://kongapi.info/konnect/". A fully-qualified type would be "https://kongapi.info/konnect/unauthenticated". The type minus its base path can be used as an error code, or key for localization.

Type Status Title Detail
unauthorized 401 Unauthorized You must be authenticated to perform this action.
forbidden 403 Forbidden You do not have permission to perform this action.
quota-exceeded 403 Quota Exceeded Maximum number of [entity_type] exceeded. Max allowed: [max].
not-found 404 Not Found The requested resource was not found.
invalid-request 400 Invalid Request The request is invalid.
conflict 409 Conflict detail varies

Notes on the above:

quota-exceeded

For enforcing resource quotas in Konnect APIs, the following properties will apply:

  • The resource quota applies to a given entity type, e.g. Control Planes (referred to as [entity_type] in its detail string).
  • The resource quota will have a non-negative integer value that indicates the allowed maximum aggregate count, or maximum value, of its given entity type (referred to as [max] in its detail string).

not-found

When the resource type is known, detail may be more specific; for example, "The requested runtime group was not found."

This error must be returned when any of the path parameters in the request are not found. When required query parameters are not found, use the invalid-request response type.

invalid-request

The detail field for this error may be more specific.

The invalid_parameters field is required. If the error cannot be resolved by correcting the issues in the invalid_parameters field, a new error type should be introduced and documentation written for it.

conflict

Use this error when the requested action is valid but can't be executed due to the current state on the server; for example,

  • attempting to insert a record that violates a unique constraint.

The detail field should describe the conflict and the step(s) to take to resolve it.

If the requested action is not valid, use invalid-request.

Adding Error Responses

When adding a new error type, consult this AIP to determine if an existing error could be reused. If not, consider whether it is a "base" error or domain-specific. For a base error, raise a PR that adds it to the above section. For domain-specific errors, raise a PR that adds it to the following table.

Type Status Title Detail

Validation FAQ

Expected behaviour is not well defined in some error cases. This list documents instances that have been discovered and resolved so far at Kong:

Q: If someone does not have access to a resource, should I return a HTTP 403 or a 404?
A: If the resource is owned by the authenticated user's current organization, return HTTP 403. Otherwise return HTTP 404 to prevent data leakage.

Q: If a parameter in a URL has a type hint (e.g. uuid, integer) and a non-valid value is passed, should I return a HTTP 400 or a 404?
A: Return HTTP 404. URLs are opaque identifiers, and the resource at that URL can not exist. Type hints in OpenAPI are hints rather than explicit validation rules. This has been confirmed by the JSON Schema maintainers in the "APIs you won't hate" Slack community.