From af6e8a2f24af0fe2e28a1d3b081d0363ce15424b Mon Sep 17 00:00:00 2001 From: Olivia Lee Date: Thu, 12 Dec 2024 23:53:43 -0800 Subject: [PATCH 1/2] remove duplicate M_THREEPID_IN_USE error code This was added in 9198182f1a5dde1350b427634430183d2499a92d, but it was already present earlier in the list, with a slightly different description. Signed-off-by: Olivia Lee --- content/client-server-api/_index.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/content/client-server-api/_index.md b/content/client-server-api/_index.md index bdee69b24..866614222 100644 --- a/content/client-server-api/_index.md +++ b/content/client-server-api/_index.md @@ -229,10 +229,6 @@ See the [Server Notices](#server-notices) module for more information. `M_THREEPID_MEDIUM_NOT_SUPPORTED` The homeserver does not support adding a third party identifier of the given medium. -`M_THREEPID_IN_USE` -The third party identifier specified by the client is not acceptable because it is -already in use in some way. - #### Rate limiting Homeservers SHOULD implement rate limiting to reduce the risk of being From 9bbb9c53979c0f6e84b2b02c3b52575ae25ec701 Mon Sep 17 00:00:00 2001 From: Olivia Lee Date: Mon, 9 Dec 2024 00:20:18 -0800 Subject: [PATCH 2/2] move standard error schema to appendices and share between all APIs I asked about this on matrix, and tulir confirmed[1] that the error schema was intended to be shared between all APIs. I would like the shared schema to be explicit in the spec text so that ruma can move to using the same error type for client-server and server-server endpoints. This would simplify error handling in server implementations. Error codes that are used in more than one API were moved to the appendices, while error codes specific to only one API were left there. Since the docs on which error codes are actually used by which endpoints aren't very complemete, I determined this by looking at the synapse source code. [1]: https://matrix.to/#/#matrix-spec-discussion:neko.dev/$Y2yTCeR_AeW6g_4jViFbx4gTE_AwF0RN7yrHJ25F5Q8 Signed-off-by: Olivia Lee --- .../newsfragments/2026.clarification | 1 + .../newsfragments/2026.clarification | 1 + .../newsfragments/2026.clarification | 1 + .../newsfragments/2026.clarification | 1 + .../newsfragments/2026.clarification | 1 + content/appendices.md | 130 ++++++++++++++++++ content/application-service-api.md | 10 ++ content/client-server-api/_index.md | 123 +---------------- content/identity-service-api.md | 40 +----- content/push-gateway-api.md | 5 + content/server-server-api.md | 5 + 11 files changed, 165 insertions(+), 153 deletions(-) create mode 100644 changelogs/appendices/newsfragments/2026.clarification create mode 100644 changelogs/application_service/newsfragments/2026.clarification create mode 100644 changelogs/client_server/newsfragments/2026.clarification create mode 100644 changelogs/identity_service/newsfragments/2026.clarification create mode 100644 changelogs/push_gateway/newsfragments/2026.clarification diff --git a/changelogs/appendices/newsfragments/2026.clarification b/changelogs/appendices/newsfragments/2026.clarification new file mode 100644 index 000000000..49eb2aef3 --- /dev/null +++ b/changelogs/appendices/newsfragments/2026.clarification @@ -0,0 +1 @@ +Move standard error response schema from client-server API to appendices. diff --git a/changelogs/application_service/newsfragments/2026.clarification b/changelogs/application_service/newsfragments/2026.clarification new file mode 100644 index 000000000..c580576a0 --- /dev/null +++ b/changelogs/application_service/newsfragments/2026.clarification @@ -0,0 +1 @@ +Specify that error responses must conform to the standard error response schema. diff --git a/changelogs/client_server/newsfragments/2026.clarification b/changelogs/client_server/newsfragments/2026.clarification new file mode 100644 index 000000000..49eb2aef3 --- /dev/null +++ b/changelogs/client_server/newsfragments/2026.clarification @@ -0,0 +1 @@ +Move standard error response schema from client-server API to appendices. diff --git a/changelogs/identity_service/newsfragments/2026.clarification b/changelogs/identity_service/newsfragments/2026.clarification new file mode 100644 index 000000000..f9b7e5ec5 --- /dev/null +++ b/changelogs/identity_service/newsfragments/2026.clarification @@ -0,0 +1 @@ +Reference standard error response schema from appendices instead of embedding it. diff --git a/changelogs/push_gateway/newsfragments/2026.clarification b/changelogs/push_gateway/newsfragments/2026.clarification new file mode 100644 index 000000000..c580576a0 --- /dev/null +++ b/changelogs/push_gateway/newsfragments/2026.clarification @@ -0,0 +1 @@ +Specify that error responses must conform to the standard error response schema. diff --git a/content/appendices.md b/content/appendices.md index 926161115..b9ae5b022 100644 --- a/content/appendices.md +++ b/content/appendices.md @@ -4,6 +4,136 @@ weight: 70 type: docs --- +## Standard error response + +Any errors which occur at the Matrix API level MUST return a "standard +error response". This is a JSON object which looks like: + +```json +{ + "errcode": "", + "error": "" +} +``` + +The `error` string will be a human-readable error message, usually a +sentence explaining what went wrong. + +The `errcode` string will be a unique string which can be used to handle an +error message e.g. `M_FORBIDDEN`. Error codes should have their namespace +first in ALL CAPS, followed by a single `_`. For example, if there was a custom +namespace `com.mydomain.here`, and a `FORBIDDEN` code, the error code should +look like `COM.MYDOMAIN.HERE_FORBIDDEN`. Error codes defined by this +specification should start with `M_`. + +Some `errcode`s define additional keys which should be present in the error +response object, but the keys `error` and `errcode` MUST always be present. + +Errors are generally best expressed by their error code rather than the +HTTP status code returned. When encountering the error code `M_UNKNOWN`, +clients should prefer the HTTP status code as a more reliable reference +for what the issue was. For example, if the client receives an error +code of `M_NOT_FOUND` but the request gave a 400 Bad Request status +code, the client should treat the error as if the resource was not +found. However, if the client were to receive an error code of +`M_UNKNOWN` with a 400 Bad Request, the client should assume that the +request being made was invalid. + +#### Common error codes + +These error codes can be returned by any API endpoint: + +`M_FORBIDDEN` +Forbidden access, e.g. joining a room without permission, failed login. + +`M_BAD_JSON` +Request contained valid JSON, but it was malformed in some way, e.g. +missing required keys, invalid values for keys. + +`M_NOT_JSON` +Request did not contain valid JSON. + +`M_NOT_FOUND` +No resource was found for this request. + +`M_LIMIT_EXCEEDED` +Too many requests have been sent in a short period of time. Wait a while +then try again. See [Rate limiting](#rate-limiting). + +`M_UNRECOGNIZED` +The server did not understand the request. This is expected to be returned with +a 404 HTTP status code if the endpoint is not implemented or a 405 HTTP status +code if the endpoint is implemented, but the incorrect HTTP method is used. + +`M_UNKNOWN` +An unknown error has occurred. + +#### Other error codes + +The following error codes are specific to certain endpoints. + + + +`M_UNAUTHORIZED` +The request was not correctly authorized. Usually due to login failures. + +`M_MISSING_PARAM` +A required parameter was missing from the request. + +`M_INVALID_PARAM` +A parameter that was specified has the wrong value. For example, the +server expected an integer and instead received a string. + +`M_TOO_LARGE` +The request or entity was too large. + +`M_EXCLUSIVE` +The resource being requested is reserved by an application service, or +the application service making the request has not created the resource. + +`M_RESOURCE_LIMIT_EXCEEDED` +The request cannot be completed because the homeserver has reached a +resource limit imposed on it. For example, a homeserver held in a shared +hosting environment may reach a resource limit if it starts using too +much memory or disk space. The error MUST have an `admin_contact` field +to provide the user receiving the error a place to reach out to. +Typically, this error will appear on routes which attempt to modify +state (e.g.: sending messages, account data, etc) and not routes which +only read state (e.g.: [`/client/sync`](/client-server-api/#get_matrixclientv3sync), +[`/client/user/{userId}/account_data/{type}`](/client-server-api/#get_matrixclientv3useruseridaccount_datatype), etc). + +`M_UNSUPPORTED_ROOM_VERSION` +The client's request to create a room used a room version that the +server does not support. + +`M_INCOMPATIBLE_ROOM_VERSION` +The client attempted to join a room that has a version the server does +not support. Inspect the `room_version` property of the error response +for the room's version. + +#### Rate limiting + +Homeservers SHOULD implement rate limiting to reduce the risk of being +overloaded. If a request is refused due to rate limiting, it should +return a standard error response of the form: + +```json +{ + "errcode": "M_LIMIT_EXCEEDED", + "error": "string", + "retry_after_ms": integer (optional, deprecated) +} +``` + +Homeservers SHOULD include a [`Retry-After`](https://www.rfc-editor.org/rfc/rfc9110#field.retry-after) +header for any response with a 429 status code. + +The `retry_after_ms` property MAY be included to tell the client how long +they have to wait in milliseconds before they can try again. This property is +deprecated, in favour of the `Retry-After` header. + +{{% changed-in v="1.10" %}}: `retry_after_ms` property deprecated in favour of `Retry-After` header. + ## Unpadded Base64 *Unpadded* Base64 refers to 'standard' Base64 encoding as defined in diff --git a/content/application-service-api.md b/content/application-service-api.md index 2882f3d97..55c3b2010 100644 --- a/content/application-service-api.md +++ b/content/application-service-api.md @@ -12,6 +12,16 @@ Application Service API (AS API) defines a standard API to allow such extensible functionality to be implemented irrespective of the underlying homeserver implementation. +## API standards + +### Standard error response + +All homeserver -> application service API endpoints MUST return error responses +conforming to the [standard error response](/appendices#standard-error-response) +schema. Similarly, all application service client-server API extension +endpoints MUST return error responses conforming to the standard error response +schema. + ## Application Services Application services are passive and can only observe events from the diff --git a/content/client-server-api/_index.md b/content/client-server-api/_index.md index 866614222..efddbecca 100644 --- a/content/client-server-api/_index.md +++ b/content/client-server-api/_index.md @@ -50,45 +50,13 @@ requirements for server responses. ### Standard error response -Any errors which occur at the Matrix API level MUST return a "standard -error response". This is a JSON object which looks like: - -```json -{ - "errcode": "", - "error": "" -} -``` - -The `error` string will be a human-readable error message, usually a -sentence explaining what went wrong. - -The `errcode` string will be a unique string which can be used to handle an -error message e.g. `M_FORBIDDEN`. Error codes should have their namespace -first in ALL CAPS, followed by a single `_`. For example, if there was a custom -namespace `com.mydomain.here`, and a `FORBIDDEN` code, the error code should -look like `COM.MYDOMAIN.HERE_FORBIDDEN`. Error codes defined by this -specification should start with `M_`. - -Some `errcode`s define additional keys which should be present in the error -response object, but the keys `error` and `errcode` MUST always be present. - -Errors are generally best expressed by their error code rather than the -HTTP status code returned. When encountering the error code `M_UNKNOWN`, -clients should prefer the HTTP status code as a more reliable reference -for what the issue was. For example, if the client receives an error -code of `M_NOT_FOUND` but the request gave a 400 Bad Request status -code, the client should treat the error as if the resource was not -found. However, if the client were to receive an error code of -`M_UNKNOWN` with a 400 Bad Request, the client should assume that the -request being made was invalid. +All client-server API endpoints MUST return error responses conforming to the +[standard error response](/appendices#standard-error-response) schema. #### Common error codes -These error codes can be returned by any API endpoint: - -`M_FORBIDDEN` -Forbidden access, e.g. joining a room without permission, failed login. +In addition to the standard error codes listed in the appendix, the following +standard error codes can be returned by any client-server API endpoint: `M_UNKNOWN_TOKEN` The access or refresh token specified was not recognised. @@ -107,36 +75,10 @@ The account has been [locked](#account-locking) and cannot be used at this time. The account has been [suspended](#account-suspension) and can only be used for limited actions at this time. -`M_BAD_JSON` -Request contained valid JSON, but it was malformed in some way, e.g. -missing required keys, invalid values for keys. - -`M_NOT_JSON` -Request did not contain valid JSON. - -`M_NOT_FOUND` -No resource was found for this request. - -`M_LIMIT_EXCEEDED` -Too many requests have been sent in a short period of time. Wait a while -then try again. See [Rate limiting](#rate-limiting). - -`M_UNRECOGNIZED` -The server did not understand the request. This is expected to be returned with -a 404 HTTP status code if the endpoint is not implemented or a 405 HTTP status -code if the endpoint is implemented, but the incorrect HTTP method is used. - -`M_UNKNOWN` -An unknown error has occurred. - #### Other error codes -The following error codes are specific to certain endpoints. - - - -`M_UNAUTHORIZED` -The request was not correctly authorized. Usually due to login failures. +In addition to the standard error codes listed in the appendix, the following +standard error codes can be returned by specific client-server API endpoints: `M_USER_DEACTIVATED` The user ID associated with the request has been deactivated. Typically @@ -179,11 +121,6 @@ that this server does not trust. The client's request to create a room used a room version that the server does not support. -`M_INCOMPATIBLE_ROOM_VERSION` -The client attempted to join a room that has a version the server does -not support. Inspect the `room_version` property of the error response -for the room's version. - `M_BAD_STATE` The state change requested cannot be performed, such as attempting to unban a user who is not banned. @@ -197,31 +134,6 @@ A Captcha is required to complete the request. `M_CAPTCHA_INVALID` The Captcha provided did not match what was expected. -`M_MISSING_PARAM` -A required parameter was missing from the request. - -`M_INVALID_PARAM` -A parameter that was specified has the wrong value. For example, the -server expected an integer and instead received a string. - -`M_TOO_LARGE` -The request or entity was too large. - -`M_EXCLUSIVE` -The resource being requested is reserved by an application service, or -the application service making the request has not created the resource. - -`M_RESOURCE_LIMIT_EXCEEDED` -The request cannot be completed because the homeserver has reached a -resource limit imposed on it. For example, a homeserver held in a shared -hosting environment may reach a resource limit if it starts using too -much memory or disk space. The error MUST have an `admin_contact` field -to provide the user receiving the error a place to reach out to. -Typically, this error will appear on routes which attempt to modify -state (e.g.: sending messages, account data, etc) and not routes which -only read state (e.g.: [`/sync`](#get_matrixclientv3sync), -[`/user/{userId}/account_data/{type}`](#get_matrixclientv3useruseridaccount_datatype), etc). - `M_CANNOT_LEAVE_SERVER_NOTICE_ROOM` The user is unable to reject an invite to join the server notices room. See the [Server Notices](#server-notices) module for more information. @@ -229,29 +141,6 @@ See the [Server Notices](#server-notices) module for more information. `M_THREEPID_MEDIUM_NOT_SUPPORTED` The homeserver does not support adding a third party identifier of the given medium. -#### Rate limiting - -Homeservers SHOULD implement rate limiting to reduce the risk of being -overloaded. If a request is refused due to rate limiting, it should -return a standard error response of the form: - -```json -{ - "errcode": "M_LIMIT_EXCEEDED", - "error": "string", - "retry_after_ms": integer (optional, deprecated) -} -``` - -Homeservers SHOULD include a [`Retry-After`](https://www.rfc-editor.org/rfc/rfc9110#field.retry-after) -header for any response with a 429 status code. - -The `retry_after_ms` property MAY be included to tell the client how long -they have to wait in milliseconds before they can try again. This property is -deprecated, in favour of the `Retry-After` header. - -{{% changed-in v="1.10" %}}: `retry_after_ms` property deprecated in favour of `Retry-After` header. - ### Transaction identifiers The client-server API typically uses `HTTP PUT` to submit requests with diff --git a/content/identity-service-api.md b/content/identity-service-api.md index 3c20a12a2..6e6325930 100644 --- a/content/identity-service-api.md +++ b/content/identity-service-api.md @@ -54,26 +54,11 @@ All JSON data, in requests or responses, must be encoded using UTF-8. ### Standard error response -Any errors which occur at the Matrix API level MUST return a "standard -error response". This is a JSON object which looks like: +All identity service API endpoints MUST return error responses conforming to +the [standard error response](/appendices#standard-error-response) schema. -```json -{ - "errcode": "", - "error": "" -} -``` - -The `error` string will be a human-readable error message, usually a -sentence explaining what went wrong. The `errcode` string will be a -unique string which can be used to handle an error message e.g. -`M_FORBIDDEN`. There may be additional keys depending on the error, but -the keys `error` and `errcode` MUST always be present. - -Some standard error codes are below: - -`M_NOT_FOUND` -The resource requested could not be located. +In addition to the standard error codes listed in the appendix, the following +standard error codes are specific to the the identity service API: `M_MISSING_PARAMS` The request was missing one or more parameters. @@ -104,23 +89,6 @@ The provided third-party address was not valid. There was an error sending a notification. Typically seen when attempting to verify ownership of a given third-party address. -`M_UNRECOGNIZED` -The request contained an unrecognised value, such as an unknown token or -medium. - -This is also used as the response if a server did not understand the request. -This is expected to be returned with a 404 HTTP status code if the endpoint is -not implemented or a 405 HTTP status code if the endpoint is implemented, but -the incorrect HTTP method is used. - -`M_THREEPID_IN_USE` -The third-party identifier is already in use by another user. Typically -this error will have an additional `mxid` property to indicate who owns -the third-party identifier. - -`M_UNKNOWN` -An unknown error has occurred. - ## Privacy Identity is a privacy-sensitive issue. While the identity server exists diff --git a/content/push-gateway-api.md b/content/push-gateway-api.md index 5fb36d7cf..8999c5a5f 100644 --- a/content/push-gateway-api.md +++ b/content/push-gateway-api.md @@ -39,6 +39,11 @@ notification provider (e.g. APNS, GCM). ## API standards +### Standard error response + +All push gateway API endpoints MUST return error responses conforming to the +[standard error response](/appendices#standard-error-response) schema. + ### Unsupported endpoints If a request for an unsupported (or unknown) endpoint is received then the server diff --git a/content/server-server-api.md b/content/server-server-api.md index 8e99c431a..f5ae67a8e 100644 --- a/content/server-server-api.md +++ b/content/server-server-api.md @@ -84,6 +84,11 @@ to be an IP address in which case SNI is not supported and should not be sent. Servers are encouraged to make use of the [Certificate Transparency](https://www.certificate-transparency.org/) project. +### Standard error response + +All server-server API endpoints MUST return error responses conforming to the +[standard error response](/appendices#standard-error-response) schema. + ### Unsupported endpoints If a request for an unsupported (or unknown) endpoint is received then the server