From adb190dce16807fe487ac5683d30484f8ac33a97 Mon Sep 17 00:00:00 2001 From: Hugh Nimmo-Smith Date: Fri, 29 Aug 2025 17:36:25 +0100 Subject: [PATCH 01/12] MSCXXXX: M_USER_LIMIT_EXCEEDED error code --- proposals/xxxx-user-limit-exceeded.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 proposals/xxxx-user-limit-exceeded.md diff --git a/proposals/xxxx-user-limit-exceeded.md b/proposals/xxxx-user-limit-exceeded.md new file mode 100644 index 00000000000..48cdce85287 --- /dev/null +++ b/proposals/xxxx-user-limit-exceeded.md @@ -0,0 +1 @@ +placeholder From 61bd9836d91c39e94272e45a24ee828c91e61595 Mon Sep 17 00:00:00 2001 From: Hugh Nimmo-Smith Date: Fri, 29 Aug 2025 18:22:38 +0100 Subject: [PATCH 02/12] Initial draft --- proposals/4335-user-limit-exceeded.md | 126 ++++++++++++++++++++++++++ proposals/xxxx-user-limit-exceeded.md | 1 - 2 files changed, 126 insertions(+), 1 deletion(-) create mode 100644 proposals/4335-user-limit-exceeded.md delete mode 100644 proposals/xxxx-user-limit-exceeded.md diff --git a/proposals/4335-user-limit-exceeded.md b/proposals/4335-user-limit-exceeded.md new file mode 100644 index 00000000000..04f4e4e7aa1 --- /dev/null +++ b/proposals/4335-user-limit-exceeded.md @@ -0,0 +1,126 @@ +# MSC4335: M_USER_LIMIT_EXCEEDED error code + +Currently, Matrix homeservers lack a standardized error code to indicate when user-related limits +have been exceeded. This creates inconsistent client experiences when homeservers need to reject +operations due to per-user quotas, rate limits, or resource constraints. + +Different implementations may return generic error codes like `M_FORBIDDEN` or `M_TOO_LARGE`, making +it difficult for clients to provide appropriate user feedback or implement proper retry logic. + +A concrete use case for this is the +[fair usage limits introduced on the matrix.org homeserver](https://matrix.org/homeserver/pricing/#usage-limits). + +This proposal introduces a new error code `M_USER_LIMIT_EXCEEDED` that homeservers can use to +signal when a user has exceeded their allocated limits, distinct from general rate limiting or +server-wide constraints. This improves the user experience by allowing clients to provide more +specific error messages and handle user-specific limitations appropriately. + + +## Proposal + +This proposal adds a new error code `M_USER_LIMIT_EXCEEDED` to the Matrix specification. This error +code should be returned when a user has exceeded limits that are specifically associated with their +account, such as: + +* **Storage quotas**: When a user has exceeded their allocated storage space for media uploads, + message history, or other persistent data. +* **Resource limits**: When a user has reached their maximum number of allowed rooms, devices, + or other account-scoped resources. +* **Feature limits**: When a user has exceeded usage limits for specific features (e.g., number + of public rooms they can create, number of invites they can send). +* **Account tier restrictions**: When a user's account type (free, premium, etc.) prevents them + from performing certain operations. + +The error should be returned with HTTP status code **403 Forbidden** to indicate that the operation +is not permitted due to the user's current limits. + +### Error Response Format + +When returning this error, servers should use the standard Matrix error response format: + +```json +{ + "errcode": "M_USER_LIMIT_EXCEEDED", + "error": "User has exceeded their storage quota of 10GB" +} +``` + +The human-readable `error` field should provide specific information about what limit was exceeded +and, where possible, include details about the current usage and limit values to help users +understand their situation. + +### Applicable Endpoints + +This error code can be returned by any Matrix Client-Server API endpoint where user-specific limits +might be enforced. Examples might include: + +* `POST /_matrix/media/v3/upload` - When storage quota is exceeded +* `POST /_matrix/client/v3/rooms/{roomId}/invite` - When invite limits (like maximum participant count) are exceeded + +The HTTP response code should be chosen based on the specification for the individual endpoint. For +example, the most appropriate code for `POST /_matrix/media/v3/upload` would be `403`. + +### Distinction from Other Error Codes + +This error code is distinct from: + +* `M_LIMIT_EXCEEDED`: Used for general rate limiting that applies to all users or based on IP/client +* `M_FORBIDDEN`: Used for authorization failures or policy violations not related to usage limits +* `M_RESOURCE_LIMIT_EXCEEDED`: Used for server-wide resource constraints affecting all users +* `M_TOO_LARGE`: Used when a request is too large (file size, message length, etc.) regardless of user limits + +## Potential issues + +This error code does not specify the exact nature of the limit that was exceeded, which could +potentially lead to ambiguity. However, this is consistent with other Matrix error codes that +rely on the human-readable `error` field to provide specific details. Implementers should ensure +they provide clear, actionable error messages. + +The error code does not provide machine-readable information about current usage or limits, +which could be useful for clients to display progress bars or usage statistics. However, adding +such fields would require a more complex specification change and could be addressed in a future +MSC if deemed necessary. + +## Alternatives + +Several alternatives were considered for this proposal: + +**Use M_RESOURCE_LIMIT_EXCEEDED**: The existing `M_RESOURCE_LIMIT_EXCEEDED` error code could be +expanded to cover user-specific limits. However, this code is currently used for server-wide +resource constraints, and overloading it could create confusion about whether the limit applies +to the user specifically or the server generally. + +**Add structured error information**: Instead of a simple error code, a more complex error format +could include machine-readable fields for limit types, current usage, and maximum limits. While +this would provide more information, it would require a more significant change to the error +response format and could be added in a future MSC if needed. + +**Multiple specific error codes**: Separate error codes could be introduced for different types +of limits (e.g., `M_STORAGE_LIMIT_EXCEEDED`, `M_ROOM_LIMIT_EXCEEDED`). However, this approach +would require many new error codes and doesn't provide significant benefits over a single code +with descriptive error messages. + +## Security considerations + +None as only adding a new error code. + +## Unstable prefix + +While this proposal is being developed and refined, implementations should use the unstable prefix +`ORG.MATRIX.MSC4335.M_USER_LIMIT_EXCEEDED` instead of `M_USER_LIMIT_EXCEEDED`. + +For example: + +```json +{ + "errcode": "ORG.MATRIX.MSC4335.M_USER_LIMIT_EXCEEDED", + "error": "User has exceeded their fair usage limit of 2GB" +} +``` + +Once the MSC is accepted and the error code is included in the Matrix specification, implementations +should transition to using the stable `M_USER_LIMIT_EXCEEDED` error code. + +## Dependencies + +None. diff --git a/proposals/xxxx-user-limit-exceeded.md b/proposals/xxxx-user-limit-exceeded.md deleted file mode 100644 index 48cdce85287..00000000000 --- a/proposals/xxxx-user-limit-exceeded.md +++ /dev/null @@ -1 +0,0 @@ -placeholder From fbd628a5cd39e7e23973a226c8348a7098c42f23 Mon Sep 17 00:00:00 2001 From: Hugh Nimmo-Smith Date: Mon, 8 Sep 2025 11:20:24 +0100 Subject: [PATCH 03/12] Add info_link field --- proposals/4335-user-limit-exceeded.md | 45 +++++++++++++-------------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/proposals/4335-user-limit-exceeded.md b/proposals/4335-user-limit-exceeded.md index 04f4e4e7aa1..253f3a24b83 100644 --- a/proposals/4335-user-limit-exceeded.md +++ b/proposals/4335-user-limit-exceeded.md @@ -18,9 +18,9 @@ specific error messages and handle user-specific limitations appropriately. ## Proposal -This proposal adds a new error code `M_USER_LIMIT_EXCEEDED` to the Matrix specification. This error -code should be returned when a user has exceeded limits that are specifically associated with their -account, such as: +This proposal adds a new [common error code](https://spec.matrix.org/v1.15/client-server-api/#common-error-codes) +`M_USER_LIMIT_EXCEEDED` to the Matrix specification. This error code should be returned when a user has exceeded +limits that are specifically associated with their account, such as: * **Storage quotas**: When a user has exceeded their allocated storage space for media uploads, message history, or other persistent data. @@ -31,35 +31,30 @@ account, such as: * **Account tier restrictions**: When a user's account type (free, premium, etc.) prevents them from performing certain operations. -The error should be returned with HTTP status code **403 Forbidden** to indicate that the operation -is not permitted due to the user's current limits. +The error response would also contain an `info_url` value which provides a URI that the client can link +the user to in order to get more context on the error. -### Error Response Format +The HTTP response code should be chosen based on the specification for the individual endpoint. For +example, the most appropriate code for `POST /_matrix/media/v3/upload` would be `403 Forbidden`. -When returning this error, servers should use the standard Matrix error response format: +An example response body for the error might look as follows: ```json { "errcode": "M_USER_LIMIT_EXCEEDED", + "info_url": "https://example.com/homeserver/?limit_type=quota", "error": "User has exceeded their storage quota of 10GB" } ``` -The human-readable `error` field should provide specific information about what limit was exceeded -and, where possible, include details about the current usage and limit values to help users -understand their situation. - ### Applicable Endpoints This error code can be returned by any Matrix Client-Server API endpoint where user-specific limits -might be enforced. Examples might include: +might be enforced. Examples could include: * `POST /_matrix/media/v3/upload` - When storage quota is exceeded * `POST /_matrix/client/v3/rooms/{roomId}/invite` - When invite limits (like maximum participant count) are exceeded -The HTTP response code should be chosen based on the specification for the individual endpoint. For -example, the most appropriate code for `POST /_matrix/media/v3/upload` would be `403`. - ### Distinction from Other Error Codes This error code is distinct from: @@ -73,8 +68,12 @@ This error code is distinct from: This error code does not specify the exact nature of the limit that was exceeded, which could potentially lead to ambiguity. However, this is consistent with other Matrix error codes that -rely on the human-readable `error` field to provide specific details. Implementers should ensure -they provide clear, actionable error messages. +rely on the human-readable `error` field to provide specific details. Instead the `info_url` +provides a way for the homeserver to apply arbitrary limits without the client having to understand +every type in advance. + +The homeserver can choose to provide localised and personalised content on the `info_url` if it +wishes. The error code does not provide machine-readable information about current usage or limits, which could be useful for clients to display progress bars or usage statistics. However, adding @@ -106,21 +105,21 @@ None as only adding a new error code. ## Unstable prefix -While this proposal is being developed and refined, implementations should use the unstable prefix -`ORG.MATRIX.MSC4335.M_USER_LIMIT_EXCEEDED` instead of `M_USER_LIMIT_EXCEEDED`. +While this proposal is being developed and refined, implementations should use the prefix the +`errcode` and `info_url` fields with `org.matrix.msc4335.` and use a value of `M_UNKNOWN` for +`errcode`. For example: ```json { - "errcode": "ORG.MATRIX.MSC4335.M_USER_LIMIT_EXCEEDED", + "errcode": "M_UNKNOWN", + "org.matrix.msc4335.errcode": "M_USER_LIMIT_EXCEEDED", + "org.matrix.msc4334.info_url": "https://example.com/homeserver/?limit_type=quota", "error": "User has exceeded their fair usage limit of 2GB" } ``` -Once the MSC is accepted and the error code is included in the Matrix specification, implementations -should transition to using the stable `M_USER_LIMIT_EXCEEDED` error code. - ## Dependencies None. From 79518f08b8b75ae0615f30eb5aa14de87d25d764 Mon Sep 17 00:00:00 2001 From: Hugh Nimmo-Smith Date: Fri, 3 Oct 2025 11:27:33 +0100 Subject: [PATCH 04/12] Update unstable values --- proposals/4335-user-limit-exceeded.md | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/proposals/4335-user-limit-exceeded.md b/proposals/4335-user-limit-exceeded.md index 253f3a24b83..e56d59c51f6 100644 --- a/proposals/4335-user-limit-exceeded.md +++ b/proposals/4335-user-limit-exceeded.md @@ -15,7 +15,6 @@ signal when a user has exceeded their allocated limits, distinct from general ra server-wide constraints. This improves the user experience by allowing clients to provide more specific error messages and handle user-specific limitations appropriately. - ## Proposal This proposal adds a new [common error code](https://spec.matrix.org/v1.15/client-server-api/#common-error-codes) @@ -105,17 +104,17 @@ None as only adding a new error code. ## Unstable prefix -While this proposal is being developed and refined, implementations should use the prefix the -`errcode` and `info_url` fields with `org.matrix.msc4335.` and use a value of `M_UNKNOWN` for -`errcode`. +While this proposal is being developed and refined, implementations should use the following: + +* `ORG.MATRIX.MSC4335_USER_LIMIT_EXCEEDED` instead of `M_USER_LIMIT_EXCEEDED` +* `org.matrix.msc4335.info_url` instead of `info_url` For example: ```json { - "errcode": "M_UNKNOWN", - "org.matrix.msc4335.errcode": "M_USER_LIMIT_EXCEEDED", - "org.matrix.msc4334.info_url": "https://example.com/homeserver/?limit_type=quota", + "errcode": "ORG.MATRIX.MSC4335_USER_LIMIT_EXCEEDED", + "org.matrix.msc4335.info_url": "https://example.com/homeserver/?limit_type=quota", "error": "User has exceeded their fair usage limit of 2GB" } ``` From 01d66ce521ba05985858812833c7802ee8de0209 Mon Sep 17 00:00:00 2001 From: Hugh Nimmo-Smith Date: Fri, 10 Oct 2025 11:05:11 +0100 Subject: [PATCH 05/12] Add soft_limit and increase_uri --- proposals/4335-user-limit-exceeded.md | 56 ++++++++++++++++++++------- 1 file changed, 41 insertions(+), 15 deletions(-) diff --git a/proposals/4335-user-limit-exceeded.md b/proposals/4335-user-limit-exceeded.md index e56d59c51f6..fb7deb21c1d 100644 --- a/proposals/4335-user-limit-exceeded.md +++ b/proposals/4335-user-limit-exceeded.md @@ -17,7 +17,7 @@ specific error messages and handle user-specific limitations appropriately. ## Proposal -This proposal adds a new [common error code](https://spec.matrix.org/v1.15/client-server-api/#common-error-codes) +This proposal adds a new [common error code](https://spec.matrix.org/v1.16/client-server-api/#common-error-codes) `M_USER_LIMIT_EXCEEDED` to the Matrix specification. This error code should be returned when a user has exceeded limits that are specifically associated with their account, such as: @@ -30,19 +30,37 @@ limits that are specifically associated with their account, such as: * **Account tier restrictions**: When a user's account type (free, premium, etc.) prevents them from performing certain operations. -The error response would also contain an `info_url` value which provides a URI that the client can link -the user to in order to get more context on the error. +The error response must also contain additional fields: + +* `info_uri` string (required) - a URI that the client can link the user to in order to get more context on the error +* `soft_limit` boolean (required) - `true` means that the specific limit encountered can be increased. `false` means + that it is a hard limit that cannot be increased. +* `increase_uri` (required if `soft_limit` is `true`) - a URI where the user can undertake actions to increase the + encountered limit. The HTTP response code should be chosen based on the specification for the individual endpoint. For -example, the most appropriate code for `POST /_matrix/media/v3/upload` would be `403 Forbidden`. +example, the most appropriate code for [`POST /_matrix/media/v3/upload`] would be `403 Forbidden`. An example response body for the error might look as follows: ```json { "errcode": "M_USER_LIMIT_EXCEEDED", - "info_url": "https://example.com/homeserver/?limit_type=quota", - "error": "User has exceeded their storage quota of 10GB" + "error": "User has exceeded their storage quota of 10GB", + "info_uri": "https://example.com/homeserver/about?limit_type=quota", + "soft_limit": true, + "increase_uri": "https://example.com/homeserver/upgrade" +} +``` + +For a hard limit: + +```json +{ + "errcode": "M_USER_LIMIT_EXCEEDED", + "error": "User has exceeded their storage quota of 10GB", + "info_uri": "https://example.com/homeserver/about?limit_type=quota", + "soft_limit": false } ``` @@ -51,8 +69,8 @@ An example response body for the error might look as follows: This error code can be returned by any Matrix Client-Server API endpoint where user-specific limits might be enforced. Examples could include: -* `POST /_matrix/media/v3/upload` - When storage quota is exceeded -* `POST /_matrix/client/v3/rooms/{roomId}/invite` - When invite limits (like maximum participant count) are exceeded +* [`POST /_matrix/media/v3/upload`] - When storage quota is exceeded +* [`POST /_matrix/client/v3/rooms/{roomId}/invite`] - When invite limits (like maximum participant count) are exceeded ### Distinction from Other Error Codes @@ -67,12 +85,12 @@ This error code is distinct from: This error code does not specify the exact nature of the limit that was exceeded, which could potentially lead to ambiguity. However, this is consistent with other Matrix error codes that -rely on the human-readable `error` field to provide specific details. Instead the `info_url` +rely on the human-readable `error` field to provide specific details. Instead the `info_uri` provides a way for the homeserver to apply arbitrary limits without the client having to understand every type in advance. -The homeserver can choose to provide localised and personalised content on the `info_url` if it -wishes. +The homeserver can choose to provide localised and personalised content on the `info_uri`, `soft_limit` and +`increase_uri` if it wishes. The error code does not provide machine-readable information about current usage or limits, which could be useful for clients to display progress bars or usage statistics. However, adding @@ -83,7 +101,7 @@ MSC if deemed necessary. Several alternatives were considered for this proposal: -**Use M_RESOURCE_LIMIT_EXCEEDED**: The existing `M_RESOURCE_LIMIT_EXCEEDED` error code could be +**Use M_RESOURCE_LIMIT_EXCEEDED**: The existing [`M_RESOURCE_LIMIT_EXCEEDED`] error code could be expanded to cover user-specific limits. However, this code is currently used for server-wide resource constraints, and overloading it could create confusion about whether the limit applies to the user specifically or the server generally. @@ -107,18 +125,26 @@ None as only adding a new error code. While this proposal is being developed and refined, implementations should use the following: * `ORG.MATRIX.MSC4335_USER_LIMIT_EXCEEDED` instead of `M_USER_LIMIT_EXCEEDED` -* `org.matrix.msc4335.info_url` instead of `info_url` +* `org.matrix.msc4335.info_uri` instead of `info_uri` +* `org.matrix.msc4335.soft_limit` instead of `soft_limit` +* `org.matrix.msc4335.increase_uri` instead of `increase_uri` For example: ```json { "errcode": "ORG.MATRIX.MSC4335_USER_LIMIT_EXCEEDED", - "org.matrix.msc4335.info_url": "https://example.com/homeserver/?limit_type=quota", - "error": "User has exceeded their fair usage limit of 2GB" + "error": "User has exceeded their fair usage limit of 2GB", + "org.matrix.msc4335.info_uri": "https://example.com/homeserver/about?limit_type=quota", + "org.matrix.msc4335.soft_limit": true, + "org.matrix.msc4335.increase_uri": "https://example.com/homeserver/upgrade" } ``` ## Dependencies None. + +[`POST /_matrix/media/v3/upload`]: https://spec.matrix.org/v1.16/client-server-api/#post_matrixmediav3upload +[`POST /_matrix/client/v3/rooms/{roomId}/invite`]: https://spec.matrix.org/v1.16/client-server-api/#thirdparty_post_matrixclientv3roomsroomidinvite +[`M_RESOURCE_LIMIT_EXCEEDED`]: https://spec.matrix.org/v1.16/client-server-api/#other-error-codes From 4dd453bf459971dfeda0138fe7250566a17081f9 Mon Sep 17 00:00:00 2001 From: Hugh Nimmo-Smith Date: Mon, 13 Oct 2025 09:18:36 +0100 Subject: [PATCH 06/12] Add note about URIs being opaque --- proposals/4335-user-limit-exceeded.md | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/proposals/4335-user-limit-exceeded.md b/proposals/4335-user-limit-exceeded.md index fb7deb21c1d..7b896c722a8 100644 --- a/proposals/4335-user-limit-exceeded.md +++ b/proposals/4335-user-limit-exceeded.md @@ -32,11 +32,15 @@ limits that are specifically associated with their account, such as: The error response must also contain additional fields: -* `info_uri` string (required) - a URI that the client can link the user to in order to get more context on the error +* `info_uri` string (required) - an opaque URI that the client can link the user to in order to get more context on the + error. * `soft_limit` boolean (required) - `true` means that the specific limit encountered can be increased. `false` means that it is a hard limit that cannot be increased. -* `increase_uri` (required if `soft_limit` is `true`) - a URI where the user can undertake actions to increase the - encountered limit. +* `increase_uri` (required if `soft_limit` is `true`) - an opaque URI where the user can undertake actions to increase + the encountered limit. + +The `info_uri` and `increase_uri` are "opaque" in the sense that the homeserver implementation may choose to encode +information, such as the type of limit encountered, within the URI but it may do so using an encoding of its choosing. The HTTP response code should be chosen based on the specification for the individual endpoint. For example, the most appropriate code for [`POST /_matrix/media/v3/upload`] would be `403 Forbidden`. @@ -89,8 +93,8 @@ rely on the human-readable `error` field to provide specific details. Instead th provides a way for the homeserver to apply arbitrary limits without the client having to understand every type in advance. -The homeserver can choose to provide localised and personalised content on the `info_uri`, `soft_limit` and -`increase_uri` if it wishes. +The homeserver can choose to provide localised and personalised content on the `info_uri` and `increase_uri` if it +wishes. The error code does not provide machine-readable information about current usage or limits, which could be useful for clients to display progress bars or usage statistics. However, adding From 48713cbaeee2b051b951d91e06bfdd41a70e6d6d Mon Sep 17 00:00:00 2001 From: Hugh Nimmo-Smith Date: Mon, 13 Oct 2025 09:40:43 +0100 Subject: [PATCH 07/12] Clarify about this being a common error code --- proposals/4335-user-limit-exceeded.md | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/proposals/4335-user-limit-exceeded.md b/proposals/4335-user-limit-exceeded.md index 7b896c722a8..609bd2c91fb 100644 --- a/proposals/4335-user-limit-exceeded.md +++ b/proposals/4335-user-limit-exceeded.md @@ -17,7 +17,7 @@ specific error messages and handle user-specific limitations appropriately. ## Proposal -This proposal adds a new [common error code](https://spec.matrix.org/v1.16/client-server-api/#common-error-codes) +This proposal adds a new [common error code] `M_USER_LIMIT_EXCEEDED` to the Matrix specification. This error code should be returned when a user has exceeded limits that are specifically associated with their account, such as: @@ -70,11 +70,13 @@ For a hard limit: ### Applicable Endpoints -This error code can be returned by any Matrix Client-Server API endpoint where user-specific limits -might be enforced. Examples could include: +As it is a [common error code], `M_USER_LIMIT_EXCEEDED` may be returned by any Matrix Client-Server API endpoint. -* [`POST /_matrix/media/v3/upload`] - When storage quota is exceeded -* [`POST /_matrix/client/v3/rooms/{roomId}/invite`] - When invite limits (like maximum participant count) are exceeded +For the purpose of illustration, practical examples could include: + +* [`POST /_matrix/media/v3/upload`] - When the server is enforcing a storage quota. +* [`POST /_matrix/client/v3/rooms/{roomId}/invite`] - When invite limits (like maximum participant count) are exceeded. +* [`POST /_matrix/client/v3/createRoom`] - When the number or type of rooms is constrained. ### Distinction from Other Error Codes @@ -120,6 +122,18 @@ of limits (e.g., `M_STORAGE_LIMIT_EXCEEDED`, `M_ROOM_LIMIT_EXCEEDED`). However, would require many new error codes and doesn't provide significant benefits over a single code with descriptive error messages. +### Define specific endpoints + +Instead of making this a [common error code] instead it could be an +["other" error code](https://spec.matrix.org/v1.16/client-server-api/#other-error-codes) and have the specific endpoints +listed. + +A downside of this is that if a homeserver wished to introduce a new type of limit or quota that was not foreseen, then +another MSC would be required to introduce it. + +Instead, by making it a [common error code] the homeserver operator has flexibility over what types of limit they +choose without requiring further coordination with clients. + ## Security considerations None as only adding a new error code. @@ -152,3 +166,5 @@ None. [`POST /_matrix/media/v3/upload`]: https://spec.matrix.org/v1.16/client-server-api/#post_matrixmediav3upload [`POST /_matrix/client/v3/rooms/{roomId}/invite`]: https://spec.matrix.org/v1.16/client-server-api/#thirdparty_post_matrixclientv3roomsroomidinvite [`M_RESOURCE_LIMIT_EXCEEDED`]: https://spec.matrix.org/v1.16/client-server-api/#other-error-codes +[common error code]: https://spec.matrix.org/v1.16/client-server-api/#common-error-codes +[`POST /_matrix/client/v3/createRoom`]: https://spec.matrix.org/v1.16/client-server-api/#post_matrixclientv3createroom From a64558b504870a5a3970308fd18c3c4714813c2a Mon Sep 17 00:00:00 2001 From: Hugh Nimmo-Smith Date: Mon, 13 Oct 2025 09:45:14 +0100 Subject: [PATCH 08/12] Make `soft_limit` optional for conciseness --- proposals/4335-user-limit-exceeded.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/proposals/4335-user-limit-exceeded.md b/proposals/4335-user-limit-exceeded.md index 609bd2c91fb..f8460e64310 100644 --- a/proposals/4335-user-limit-exceeded.md +++ b/proposals/4335-user-limit-exceeded.md @@ -34,8 +34,8 @@ The error response must also contain additional fields: * `info_uri` string (required) - an opaque URI that the client can link the user to in order to get more context on the error. -* `soft_limit` boolean (required) - `true` means that the specific limit encountered can be increased. `false` means - that it is a hard limit that cannot be increased. +* `soft_limit` boolean (optional, default `false`) - `true` means that the specific limit encountered can be increased. + Otherwise it is a hard limit that cannot be increased. * `increase_uri` (required if `soft_limit` is `true`) - an opaque URI where the user can undertake actions to increase the encountered limit. @@ -63,8 +63,7 @@ For a hard limit: { "errcode": "M_USER_LIMIT_EXCEEDED", "error": "User has exceeded their storage quota of 10GB", - "info_uri": "https://example.com/homeserver/about?limit_type=quota", - "soft_limit": false + "info_uri": "https://example.com/homeserver/about?limit_type=quota" } ``` From 29d1e50cd3903111e772a13e01cf43d279040fa4 Mon Sep 17 00:00:00 2001 From: Hugh Nimmo-Smith Date: Wed, 15 Oct 2025 10:37:09 +0200 Subject: [PATCH 09/12] Incorporate notes about why extending M_RESOURCE_LIMIT_EXCEEDED is not the obvious choice --- proposals/4335-user-limit-exceeded.md | 31 +++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/proposals/4335-user-limit-exceeded.md b/proposals/4335-user-limit-exceeded.md index f8460e64310..14516cc3dfa 100644 --- a/proposals/4335-user-limit-exceeded.md +++ b/proposals/4335-user-limit-exceeded.md @@ -106,17 +106,36 @@ MSC if deemed necessary. Several alternatives were considered for this proposal: -**Use M_RESOURCE_LIMIT_EXCEEDED**: The existing [`M_RESOURCE_LIMIT_EXCEEDED`] error code could be -expanded to cover user-specific limits. However, this code is currently used for server-wide -resource constraints, and overloading it could create confusion about whether the limit applies -to the user specifically or the server generally. +### Use M_RESOURCE_LIMIT_EXCEEDED -**Add structured error information**: Instead of a simple error code, a more complex error format +The existing [`M_RESOURCE_LIMIT_EXCEEDED`] looks very similar at first glance. + +However, this code is explicitly referring to a limit being applied to the *server* and not to the *user* themselves: + +> 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. + +As such this error code is currently rendered by +[existing](https://github.com/element-hq/element-web/blob/c96da5dbf8e20ced4a512a03a75c91f8680e8d40/src/i18n/strings/en_EN.json#L1112) +[clients](https://github.com/element-hq/element-ios/blob/2dc7b76c44545b3d027cdf0196c6af6eba8932f4/Riot/Assets/en.lproj/Vector.strings#L615) +as something similar to: + +> This homeserver has exceeded one of its resource limits + +As such, I think this message would be confusing to users the interim whilst clients updated their implementations and +that a new error code would be the best way forward. + +### Add structured error information** + +Instead of a simple error code, a more complex error format could include machine-readable fields for limit types, current usage, and maximum limits. While this would provide more information, it would require a more significant change to the error response format and could be added in a future MSC if needed. -**Multiple specific error codes**: Separate error codes could be introduced for different types +### Multiple specific error codes + +Separate error codes could be introduced for different types of limits (e.g., `M_STORAGE_LIMIT_EXCEEDED`, `M_ROOM_LIMIT_EXCEEDED`). However, this approach would require many new error codes and doesn't provide significant benefits over a single code with descriptive error messages. From ce527edec0be8609f60b97cb06fc67b0ef6b19b4 Mon Sep 17 00:00:00 2001 From: Hugh Nimmo-Smith Date: Wed, 15 Oct 2025 09:51:41 +0100 Subject: [PATCH 10/12] Fix section header --- proposals/4335-user-limit-exceeded.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/4335-user-limit-exceeded.md b/proposals/4335-user-limit-exceeded.md index 14516cc3dfa..b0ffce830de 100644 --- a/proposals/4335-user-limit-exceeded.md +++ b/proposals/4335-user-limit-exceeded.md @@ -126,7 +126,7 @@ as something similar to: As such, I think this message would be confusing to users the interim whilst clients updated their implementations and that a new error code would be the best way forward. -### Add structured error information** +### Add structured error information Instead of a simple error code, a more complex error format could include machine-readable fields for limit types, current usage, and maximum limits. While From 721928be1fe1bc727212a6e31b2dd359de8b3251 Mon Sep 17 00:00:00 2001 From: Hugh Nimmo-Smith Date: Wed, 29 Oct 2025 14:21:21 +0000 Subject: [PATCH 11/12] Clarify that URIs can vary --- proposals/4335-user-limit-exceeded.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/proposals/4335-user-limit-exceeded.md b/proposals/4335-user-limit-exceeded.md index b0ffce830de..d7419fce55f 100644 --- a/proposals/4335-user-limit-exceeded.md +++ b/proposals/4335-user-limit-exceeded.md @@ -33,7 +33,7 @@ limits that are specifically associated with their account, such as: The error response must also contain additional fields: * `info_uri` string (required) - an opaque URI that the client can link the user to in order to get more context on the - error. + encountered limit. * `soft_limit` boolean (optional, default `false`) - `true` means that the specific limit encountered can be increased. Otherwise it is a hard limit that cannot be increased. * `increase_uri` (required if `soft_limit` is `true`) - an opaque URI where the user can undertake actions to increase @@ -42,6 +42,9 @@ The error response must also contain additional fields: The `info_uri` and `increase_uri` are "opaque" in the sense that the homeserver implementation may choose to encode information, such as the type of limit encountered, within the URI but it may do so using an encoding of its choosing. +The homeserver may return *different* values for `info_uri` and `increase_uri` depending on what type of limit was +reached. + The HTTP response code should be chosen based on the specification for the individual endpoint. For example, the most appropriate code for [`POST /_matrix/media/v3/upload`] would be `403 Forbidden`. From e695894e43c8529fb729451f6d55bb4f192ec32b Mon Sep 17 00:00:00 2001 From: Hugh Nimmo-Smith Date: Wed, 29 Oct 2025 14:21:43 +0000 Subject: [PATCH 12/12] Add alternatives about server side translation --- proposals/4335-user-limit-exceeded.md | 71 +++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/proposals/4335-user-limit-exceeded.md b/proposals/4335-user-limit-exceeded.md index d7419fce55f..c3f8f7d8303 100644 --- a/proposals/4335-user-limit-exceeded.md +++ b/proposals/4335-user-limit-exceeded.md @@ -155,6 +155,75 @@ another MSC would be required to introduce it. Instead, by making it a [common error code] the homeserver operator has flexibility over what types of limit they choose without requiring further coordination with clients. +### Use server side translations + +This could be similar to what is proposed generically by [MSC4176], but would need to support some form of markup rather +than just plain text in order to allow linking to external resources. + +If the homeserver wanted to communicate a "soft" limit then it could return something like: + +```json +{ + "errcode": "M_USER_LIMIT_EXCEEDED", + "error": "User has exceeded a media upload limit", + "messages": { + "en": "You have reached your daily upload limit. More information on the usage limits that apply to your account is available here. You can upgrade to a Premium account to increase the limits here.", + "fr": "Vous avez atteint votre limite de téléchargement quotidienne. Pour plus d'informations sur les limites d'utilisation applicables à votre compte, cliquez ici. Vous pouvez passer à un compte Premium pour augmenter ces limites ici.", + } +} +``` + +Similarly for a "hard" limit: + +```json +{ + "errcode": "M_USER_LIMIT_EXCEEDED", + "error": "User has exceeded a media upload limit", + "messages": { + "en": "You have reached your daily upload limit. More information on the usage limits that apply to your account is available here.", + "fr": "Vous avez atteint votre limite de téléchargement quotidienne. Pour plus d'informations sur les limites d'utilisation applicables à votre compte, cliquez ici.", + } +} +``` + +Comparison: + +* An advantage is that the homeserver can be as specific as it wishes with the messages. For example, the matrix.org + homeserver can specifically refer to the usage plans that are available rather than having to be generic. +* The size of the error response payload increases significantly. [MSC4176] has some discussion around using a header + such as `Accept-Language` or a query parameter to reduce the number of translations returned. +* A change in behaviour for clients: ordinarily the client picks the wording that is used to describe things in the + client User Interface, this would move responsibility to the server. However, this is no different from how the + [OAuth 2.0 API] makes the server responsible for translations relating to login and registration screens. + +### Server side translation with client side translation fallback + +This combines the benefits of above, with a client side fallback for servers that don't provide translations. + +The client would use the value from `messages` if a matching language is found, otherwise it can fallback to use generic +strings like in the main proposal. + +An example might be: + +```json +{ + "errcode": "M_USER_LIMIT_EXCEEDED", + "error": "User has exceeded a media upload limit", + "info_uri": "https://example.com/homeserver/about?limit_type=quota", + "soft_limit": true, + "increase_uri": "https://example.com/homeserver/upgrade", + "messages": { + "en": "You have reached your daily upload limit. More information on the usage limits that apply to your account is available here. You can upgrade to a Premium account to increase the limits here.", + "fr": "Vous avez atteint votre limite de téléchargement quotidienne. Pour plus d'informations sur les limites d'utilisation applicables à votre compte, cliquez ici. Vous pouvez passer à un compte Premium pour augmenter ces limites ici.", + } +} +``` + +So for English and French the client could show the specific messages provided by the homeserver, but for German the +client would pick the message with it's own translations. + +A downside of this is inconsistency in wording across languages depending on what the server provided. + ## Security considerations None as only adding a new error code. @@ -189,3 +258,5 @@ None. [`M_RESOURCE_LIMIT_EXCEEDED`]: https://spec.matrix.org/v1.16/client-server-api/#other-error-codes [common error code]: https://spec.matrix.org/v1.16/client-server-api/#common-error-codes [`POST /_matrix/client/v3/createRoom`]: https://spec.matrix.org/v1.16/client-server-api/#post_matrixclientv3createroom +[MSC4176]: https://github.com/matrix-org/matrix-spec-proposals/pull/4176 +[OAuth 2.0 API]: https://spec.matrix.org/v1.16/client-server-api/#oauth-20-api