louislam/uptime-kuma · error · Error

Received unexpected status code ${result.status} from notifi

Error message

Received unexpected status code ${result.status} from notification provider HaloPSA

What it means

HaloPSA.js:67-73. After POSTing the alert payload to notification.halowebhookurl, the provider only accepts 200/201/204. Any other HTTP status — even a 2xx like 202, or a 3xx/4xx/5xx — trips this generic message.

Source

Thrown at server/notification-providers/HaloPSA.js:73

            };

            if (notification.haloUsername && notification.haloPassword) {
                const data = notification.haloUsername + ":" + notification.haloPassword;
                const base64data = Buffer.from(data).toString("base64");

                config.headers.Authorization = `Basic ${base64data}`;
            }

            config = this.getAxiosConfigWithProxy(config);

            const result = await axios.post(notification.halowebhookurl, payload, config);

            // Check for successful HTTP response
            if (result.status === 200 || result.status === 201 || result.status === 204) {
                return okMsg;
            }

            throw new Error(`Received unexpected status code ${result.status} from notification provider HaloPSA`);
        } catch (error) {
            this.throwGeneralAxiosError(error);
        }
    }
}

module.exports = HaloPSA;

View on GitHub (pinned to 6b5ea01557)

Solutions

  1. Capture result.status from logs and act on the specific code: 401/403 → fix credentials; 404 → fix URL; 429 → reduce alert volume; 5xx → HaloPSA-side incident.
  2. Verify notification.halowebhookurl points to the active HaloPSA webhook endpoint.
  3. If HaloPSA legitimately returns 202, extend the allow-list to include it.
  4. Re-issue the HaloPSA API token and update it in the notification config.

Example fix

// before: if (result.status === 200 || result.status === 201 || result.status === 204)
// after: include 202 Accepted for queued webhooks
if ([200, 201, 202, 204].includes(result.status)) { return okMsg; }
Defensive patterns

Strategy: validation

Validate before calling

// Confirm URL shape + non-empty webhook before sending
function validateHaloWebhook(notification) {
    const u = notification.halowebhookurl;
    if (!u || !/^https?:\/\/.+/.test(u)) throw new Error('HaloPSA webhook URL missing/invalid');
    return u;
}

Type guard

function isHaloResponseOk(s) { return s === 200 || s === 201 || s === 204; }

Try / catch

try { await provider.send(notification, msg, monitorJSON, heartbeatJSON); }
catch (e) {
    if (/unexpected status code (\d+)/.test(e.message)) {
        const code = +e.message.match(/(\d+)/)[1];
        if (code === 401 || code === 403) log.error('HaloPSA auth failed — rotate token');
        if (code >= 500) heartbeat.status = PENDING; // transient — retry next cycle
    }
}

Prevention

When it happens

Trigger: HaloPSA webhook URL wrong/expired (404), auth header missing/wrong (401/403), webhook rate-limited (429), HaloPSA backend error (500), or a 202 Accepted that the strict allow-list does not include.

Common situations: Webhook URL copied from the wrong HaloPSA instance; integration API key rotated but not updated in Uptime Kuma; HaloPSA returns 202 for queued webhooks which this provider treats as failure.

Related errors


AI-assisted analysis of louislam/uptime-kuma@6b5ea01557 (2026-08-12). Data as JSON: /api/errors/7a6d9611cfc19235. Report an issue: GitHub.