RocketChat/Rocket.Chat · error · Error

Failed to get apps status from instance ${instanceId}

Error message

Failed to get apps status from instance ${instanceId}

What it means

The Enterprise matrix local service aggregates per-app status across instances by fanning out broker.call('matrix.getAppsStatus', null, { nodeID: instanceId }) to each node. If a target instance responds with a falsy payload (undefined/null/empty), the per-instance task throws `Failed to get apps status from instance ${instanceId}`, failing the whole status collection. A falsy result means that node had no apps status to report - typically its Apps engine is not running or not ready.

Source

Thrown at apps/meteor/ee/server/local-services/instance/service.ts:239

			throw new AppsEngineNoNodesFoundError();
		}

		const control: Promise<void>[] = [];
		const statusByApp: AppStatusReport = {};

		instances.forEach((instance) => {
			const { id: instanceId } = instance;

			control.push(
				(async () => {
					const appsStatus = await this.broker.call<Awaited<ReturnType<(typeof Apps)['getAppsStatusLocal']>>, null>(
						'matrix.getAppsStatus',
						null,
						{ nodeID: instanceId },
					);

					if (!appsStatus) {
						throw new Error(`Failed to get apps status from instance ${instanceId}`);
					}

					appsStatus.forEach(({ status, appId }) => {
						if (!statusByApp[appId]) {
							statusByApp[appId] = [];
						}

						statusByApp[appId].push({ instanceId, isLocal: instance.local, status });
					});
				})(),
			);
		});

		await Promise.all(control);

		return statusByApp;
	}
}

View on GitHub (pinned to b2c16d5842)

Solutions

  1. Inspect the named instanceId: check its logs and broker connectivity, confirm its Apps service finished startup, and restart the node if stuck.
  2. Ensure all instances run compatible versions of the matrix/apps services before aggregating status.
  3. Retry the status operation once the instance is ready; if a node is permanently empty, remove or repair it in the matrix.

Example fix

// before
const status = await appsStatusService.getAppsStatus(); // one unready instance -> whole call throws

// after - retry briefly to ride out instance startup
let status;
for (let attempt = 0; attempt < 3; attempt++) {
	try {
		status = await appsStatusService.getAppsStatus();
		break;
	} catch (e: any) {
		if (!/Failed to get apps status from instance/.test(e?.message) || attempt === 2) throw e;
		await sleep(1000 * (attempt + 1)); // instance may still be starting
	}
}
Defensive patterns

Strategy: retry

Try / catch

let lastErr;
for (let attempt = 0; attempt < 3; attempt++) {
	try {
		return await getAppsStatusAggregated();
	} catch (e: any) {
		if (!/Failed to get apps status from instance/.test(e?.message)) throw e;
		lastErr = e;
		await sleep(1000 * (attempt + 1)); // instance may still be starting/rejoining
	}
}
throw lastErr; // after retries, report the failing instanceId from the message

Prevention

When it happens

Trigger: Invoking the aggregated apps-status operation in a multi-instance (matrix) deployment while one instance is mid-startup, restarting, running a version without the Apps service, or otherwise answering empty from getAppsStatus. A single bad instance aborts the batch because all per-instance promises are collected and awaited together.

Common situations: Rolling restarts where a node has not finished initializing its Apps engine; version skew between nodes in the matrix; a node that just rejoined after a disconnect; instances with zero apps returning undefined instead of an empty array.

Related errors


AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18). Data as JSON: /api/errors/aa9c5dfe74426bad. Report an issue: GitHub.