louislam/uptime-kuma · error · Error
${WS_ERR_CODE[code] || `Unexpected status code: ${code}`}
Error message
${WS_ERR_CODE[code] || `Unexpected status code: ${code}`} What it means
In WebSocketMonitorType.check (websocket-upgrade.js:31-51). attemptUpgrade returned a close code, but it is neither in the user's accepted_statuscodes_json list nor in the built-in WS_ERR_CODE map (codes 1002-1015, 3000/3003/3008). The thrown message is the friendly name when known, else 'Unexpected status code: <code>'.
Source
Thrown at server/monitor-types/websocket-upgrade.js:43
class WebSocketMonitorType extends MonitorType {
name = "websocket-upgrade";
/**
* @inheritdoc
*/
async check(monitor, heartbeat, _server) {
const [message, code] = await this.attemptUpgrade(monitor);
if (typeof code !== "undefined") {
// If returned status code matches user controlled accepted status code(default 1000), return success
if (checkStatusCode(code, JSON.parse(monitor.accepted_statuscodes_json))) {
heartbeat.status = UP;
heartbeat.msg = message;
return; // success at this point
}
// Throw an error using friendly name if defined, fallback to generic msg
throw new Error(WS_ERR_CODE[code] || `Unexpected status code: ${code}`);
}
// If no close code, then an error has occurred, display to user
if (typeof message !== "undefined") {
throw new Error(`${message}`);
}
// Throw generic error if nothing is defined, should never happen
throw new Error("Unknown Websocket Error");
}
/**
* Builds the WebSocket options object for authentication and TLS.
* Supports basic auth, OAuth2 client credentials, and mTLS.
* @param {object} monitor The monitor object for input parameters.
* @returns {Promise<object>} The options object to pass to the WebSocket constructor.
*/
async buildWsOptions(monitor) {
const options = {};
View on GitHub (pinned to 6b5ea01557)
Solutions
- Add the observed code to the monitor's Accepted Status Codes list (accepted_statuscodes_json).
- If the code is 1006, investigate network/proxy interruption rather than adjusting accepted codes.
- Verify the WebSocket URL, subprotocol, and auth headers are correct so the server does not close with 1011/3xxx.
- Confirm reverse-proxy WebSocket upgrade support (e.g. nginx `proxy_set_header Upgrade $http_upgrade`).
Example fix
// before: accepted_statuscodes_json = [1000] // server legitimately closes with 1001 (Going Away) during deploys // after: accepted_statuscodes_json = [1000, 1001]
Defensive patterns
Strategy: validation
Validate before calling
// Confirm the close code the server is likely to send is whitelisted
const WS_ERR_CODE = { 1000:'Normal', 1001:'Going Away', 1002:'Protocol error', 1011:'Internal Error', 1015:'TLS Handshake' /* ... */ };
function ensureCodeAccepted(code, acceptedJson) {
const accepted = new Set(JSON.parse(acceptedJson || '[]'));
if (!accepted.has(code)) {
throw new Error(`WS close code ${code} (${WS_ERR_CODE[code]||'unknown'}) is not in accepted_statuscodes`);
}
} Type guard
function isWsCloseCode(v) { return typeof v === 'number' && v >= 1000 && v <= 4999; } Try / catch
try {
await monitor.check(monitor, heartbeat, server);
} catch (e) {
// 1006 = abnormal closure — treat as network, not app-level, failure
heartbeat.status = /Abnormal Closure|1006/.test(e.message) ? PENDING : DOWN;
heartbeat.msg = e.message;
} Prevention
- Mirror your reverse-proxy/expected close codes into accepted_statuscodes_json.
- Investigate recurring 1006 separately — it is almost always network, not config.
When it happens
Trigger: Server closes with 1006 (abnormal closure / TCP drop), 1011 (internal server error), an application-level 4xxx code not whitelisted, or a 1000/1001 normal close that the user forgot to add to accepted_statuscodes_json.
Common situations: Default accepted codes do not match what the gateway returns; upstream reverse proxy (nginx/cloudflare) closes idle WebSockets with 1006; auth failure surfaces as a 3xxx code that is not whitelisted.
Related errors
- Packet size must be between ${PING_PACKET_SIZE_MIN} and ${PI
- No Resolver Servers specified. Please specify at least one r
- None of the configured resolver servers could be resolved to
- ${message}
- Unknown Websocket Error
AI-assisted analysis of louislam/uptime-kuma@6b5ea01557 (2026-08-12).
Data as JSON: /api/errors/4ba64da53130be2d.
Report an issue: GitHub.