diff --git a/pkg/webui/lib/errors/utils.js b/pkg/webui/lib/errors/utils.js
index 8c0ebb0510..e4e2433ca1 100644
--- a/pkg/webui/lib/errors/utils.js
+++ b/pkg/webui/lib/errors/utils.js
@@ -598,12 +598,17 @@ export const ingestError = (error, extras = {}, tags = {}) => {
* @param {object} error - The error object.
* @returns {object|undefined} - The corresponding error message, or undefined if no match.
*/
+const qrCodeSuffix = 'Scan the QR code on the gateway to open the Gateway Status page.'
+
export const getClaimGatewayErrorMessage = error => {
const m = defineMessages({
notFound: "Gateway doesn't exist. Please confirm that the gateway EUI is correct.",
- subscriptionNotActive:
- 'There is no gateway subscription attached or active. Please get a Gateway Subscription or activate your subscription following the steps in the documentation. If this gateway is part of a fleet, you should use a Fleet Owner Token during the registration process.',
+ subscriptionDetached: `The gateway billing is detached. ${qrCodeSuffix}`,
+ subscriptionSuspended: `Your gateway billing is suspended. ${qrCodeSuffix}`,
+ subscriptionUnknown: `The gateway billing is not set up yet. ${qrCodeSuffix}`,
+ noSlotsAvailable: `There are no available Gateway Licenses for this gateway. ${qrCodeSuffix}`,
permissionDenied: 'The owner token is invalid.',
+ fleetIdMismatch: `The gateway EUI matches a Gateway License, but the fleet ID does not match. ${qrCodeSuffix}`,
})
const rootCause = getBackendErrorRootCause(error)
@@ -613,11 +618,27 @@ export const getClaimGatewayErrorMessage = error => {
case 5: // NOT_FOUND
return m.notFound
case 9: // FAILED_PRECONDITION
- if (backendErrorMessage.includes('gateway subscription not attached and active')) {
- return m.subscriptionNotActive
+ if (backendErrorMessage.includes('no available slots in gateway fleet')) {
+ return m.noSlotsAvailable
+ }
+ if (backendErrorMessage.includes('gateway subscription is detached')) {
+ return m.subscriptionDetached
+ }
+
+ if (backendErrorMessage.includes('gateway subscription is suspended')) {
+ return m.subscriptionSuspended
+ }
+
+ if (backendErrorMessage.includes('gateway subscription is not set')) {
+ return m.subscriptionUnknown
}
return undefined
case 7: // PERMISSION_DENIED
+ if (
+ backendErrorMessage.includes('slot found with the gateway ID, but fleet ID does not match')
+ ) {
+ return m.fleetIdMismatch
+ }
return m.permissionDenied
default:
return undefined
diff --git a/pkg/webui/locales/en.json b/pkg/webui/locales/en.json
index 1a7e43bd40..9d6ee65f21 100644
--- a/pkg/webui/locales/en.json
+++ b/pkg/webui/locales/en.json
@@ -1088,8 +1088,12 @@
"lib.errors.status-code-messages.503": "Service unavailable",
"lib.errors.status-code-messages.504": "Gateway timeout",
"lib.errors.utils.notFound": "Gateway doesn't exist. Please confirm that the gateway EUI is correct.",
- "lib.errors.utils.subscriptionNotActive": "There is no gateway subscription attached or active. Please get a Gateway Subscription or activate your subscription following the steps in the documentation. If this gateway is part of a fleet, you should use a Fleet Owner Token during the registration process.",
+ "lib.errors.utils.subscriptionDetached": "The gateway billing is detached. Scan the QR code on the gateway to open the Gateway Status page.",
+ "lib.errors.utils.subscriptionSuspended": "Your gateway billing is suspended. Scan the QR code on the gateway to open the Gateway Status page.",
+ "lib.errors.utils.subscriptionUnknown": "The gateway billing is not set up yet. Scan the QR code on the gateway to open the Gateway Status page.",
+ "lib.errors.utils.noSlotsAvailable": "There are no available Gateway Licenses for this gateway. Scan the QR code on the gateway to open the Gateway Status page.",
"lib.errors.utils.permissionDenied": "The owner token is invalid.",
+ "lib.errors.utils.fleetIdMismatch": "The gateway EUI matches a Gateway License, but the fleet ID does not match. Scan the QR code on the gateway to open the Gateway Status page.",
"lib.field-description-messages.idLocation": "Enter a value using lowercase letters, numbers, and dashes. You can choose this freely.",
"lib.field-description-messages.freqPlanDescription": "A frequency plan defines data rates that your end device or gateway is setup to use. It is important that gateways and end devices within reach use the same frequency plan to be able to communicate.",
"lib.field-description-messages.freqPlanLocation": "Your end device or gateway manufacturer should provide information about the applicable frequency plan for a particular device. In some cases they are printed on the device itself but they should always be in the hardware manual or data sheet.",
diff --git a/pkg/webui/locales/ja.json b/pkg/webui/locales/ja.json
index 52c3e95504..90881a1b69 100644
--- a/pkg/webui/locales/ja.json
+++ b/pkg/webui/locales/ja.json
@@ -1088,8 +1088,12 @@
"lib.errors.status-code-messages.503": "",
"lib.errors.status-code-messages.504": "",
"lib.errors.utils.notFound": "",
- "lib.errors.utils.subscriptionNotActive": "",
+ "lib.errors.utils.subscriptionDetached": "",
+ "lib.errors.utils.subscriptionSuspended": "",
+ "lib.errors.utils.subscriptionUnknown": "",
+ "lib.errors.utils.noSlotsAvailable": "",
"lib.errors.utils.permissionDenied": "",
+ "lib.errors.utils.fleetIdMismatch": "",
"lib.field-description-messages.idLocation": "",
"lib.field-description-messages.freqPlanDescription": "周波数プランは、エンドデバイスやゲートウェイが使用するように設定されたデータレートを定義します。ゲートウェイとエンドデバイスが通信できるようにするためには、同じ周波数プランを使用することが重要です",
"lib.field-description-messages.freqPlanLocation": "エンドデバイスやゲートウェイのメーカーは、特定のデバイスに適用される周波数プランに関する情報を提供するはずです。場合によっては、デバイス自体に印刷されていることもありますが、常にハードウェアマニュアルまたはデータシートに記載されているはずです",