louislam/uptime-kuma · error · Error
Ooredoo rejected the message: ${reason}
Error message
Ooredoo rejected the message: ${reason} What it means
The Ooredoo SMS gateway returns HTTP 200 even on logical failure, so the provider checks resp.data.response_code and treats non-zero as failure, throwing 'Ooredoo rejected the message: <reason>'. reason is resp.data.response_message when present, otherwise 'response_code=<code or unknown>'. This is the gateway-level acceptance check, distinct from a transport error.
Source
Thrown at server/notification-providers/ooredoo.js:59
const batch = recipients.slice(i, i + MAX_RECIPIENTS_PER_REQUEST);
const data = new URLSearchParams({
username: notification.ooredooUsername,
// The gateway expects the access key to be Base64 encoded.
access_key: Buffer.from(notification.ooredooAccessKey).toString("base64"),
message: msg,
batch: batch.join(" "),
});
const resp = await axios.post(url, data.toString(), config);
// The gateway returns HTTP 200 even on failure; the real outcome
// is carried in "response_code" (0 means the batch was accepted).
if (!resp.data || Number(resp.data.response_code) !== 0) {
const reason =
resp.data && resp.data.response_message
? resp.data.response_message
: "response_code=" + (resp.data ? resp.data.response_code : "unknown");
throw new Error("Ooredoo rejected the message: " + reason);
}
}
return okMsg;
} catch (error) {
this.throwGeneralAxiosError(error);
}
}
/**
* Normalize a Maldivian phone number to the "960XXXXXXX" format expected
* by the Ooredoo gateway. Numbers already in that form are returned as is.
* @param {string} phoneNumber The phone number to normalize
* @returns {string} The normalized phone number, or "" if it is empty
*/
normalizePhoneNumber(phoneNumber) {
const number = phoneNumber.replace(/[\s+]/g, "");
View on GitHub (pinned to 6b5ea01557)
Solutions
- Read response_message in the surfaced error to get the gateway's stated reason and act on it (top up credit, fix sender id, etc.).
- Confirm ooredooBearerToken is the current valid token and the account is active in the Ooredoo portal.
- Validate recipient numbers pass normalizePhoneNumber before sending (see error 171).
- If response_code is missing entirely, treat it as a gateway/envelope change and inspect resp.data.
Defensive patterns
Strategy: try-catch
Validate before calling
if (!notification.ooredooBearerToken) {
throw new Error("ooredooBearerToken is required");
} Type guard
/** @param {unknown} data */
function isOoredooAccepted(data) {
return data && typeof data === "object" && Number(data.response_code) === 0;
} Try / catch
const resp = await axios.post(url, data.toString(), config);
if (!isOoredooAccepted(resp.data)) {
const reason = resp.data?.response_message || `response_code=${resp.data?.response_code ?? "unknown"}`;
throw new Error(`Ooredoo rejected the message: ${reason}`);
} Prevention
- Treat response_code === 0 as the only success signal, not HTTP 200.
- Surface response_message so the gateway's reason is visible.
- Monitor account credit and sender-id approval proactively.
When it happens
Trigger: response_code !== 0: invalid/insufficient credit, malformed recipient numbers rejected by the gateway, wrong sender id, expired/invalid ooredooBearerToken accepted at transport but rejected at logic, or rate/quota limits.
Common situations: Ooredoo account out of credits; sender id not approved; recipient numbers blacklisted/off-network; token valid for auth but account suspended.
Related errors
- ${response.data?.errorMsg ?? "SMSPlanet server did not respo
- Could not connect to Cellsynt, please try again.
- Flowtriq notification failed with status code ${result.statu
- ${error.response.data ? error.response.data : "Error without
- Nextcloud Talk Error ${result?.status ?? "Unknown"}
AI-assisted analysis of louislam/uptime-kuma@6b5ea01557 (2026-08-12).
Data as JSON: /api/errors/eac0901813cbdca6.
Report an issue: GitHub.