RocketChat/Rocket.Chat · warning
Could not fetch cluster status for app
Error message
Could not fetch cluster status for app
What it means
GET /api/v1/apps/:id/status augments the local app status with per-instance status from the rest of the deployment: in microservices mode it calls Apps.getAppsStatusInNodes(), otherwise Instance.getAppsStatusInInstances() (internal RPC to other node instances). If that cluster-wide query throws, 'Could not fetch cluster status for app' is logged with the appId and error, and the endpoint still returns 200 containing the local status but no clusterStatus field.
Source
Thrown at apps/meteor/ee/server/apps/communication/rest.ts:1282
{ authRequired: true, permissionsRequired: ['manage-apps'] },
{
async get() {
const app = manager.getOneById(this.urlParams.id);
if (!app) {
return API.v1.notFound(`No App found by the id of: ${this.urlParams.id}`);
}
const response: { status: AppStatus; clusterStatus?: AppStatusReport[string] } = { status: await app.getStatus() };
try {
const clusterStatus = await fetchAppsStatusFromCluster();
if (clusterStatus?.[app.getID()]) {
response.clusterStatus = clusterStatus[app.getID()];
}
} catch (e) {
orchestrator.getRocketChatLogger().warn({ msg: 'Could not fetch cluster status for app', appId: app.getID(), err: e });
}
return API.v1.success(response);
},
async post() {
const { id: appId } = this.urlParams;
const { status } = this.bodyParams;
if (!status || typeof status !== 'string') {
return API.v1.failure('Invalid status provided, it must be "status" field and a string.');
}
const prl = manager.getOneById(appId);
if (!prl) {
return API.v1.notFound(`No App found by the id of: ${appId}`);
}
if (AppStatusUtils.isEnabled(status)) {View on GitHub (pinned to b2c16d5842)
Solutions
- Treat the response as valid but degraded - use status and treat clusterStatus as optional
- Check instance/broker health (instance registry, broker connectivity) and restart or wait out the unreachable instance
- Retry the status call once the cluster stabilizes
- Verify all nodes run compatible versions so the status RPC contract matches
Defensive patterns
Strategy: fallback
Validate before calling
// callers: validate the optional shape before reading cluster info const isAppStatusReport = (v: unknown): v is Record<string, unknown> => typeof v === 'object' && v !== null && 'status' in v;
Type guard
type AppStatusResponse = { status: string; clusterStatus?: Record<string, { instanceId: string; status: string }[]> };
const hasClusterStatus = (r: AppStatusResponse): r is AppStatusResponse & Required<Pick<AppStatusResponse, 'clusterStatus'>> =>
r.clusterStatus !== undefined && Object.keys(r.clusterStatus).length > 0; Try / catch
try {
const clusterStatus = await fetchAppsStatusFromCluster();
response.clusterStatus = clusterStatus?.[appId]; // optional enrichment
} catch {
// degrade gracefully: serve local status only, log for observability
} Prevention
- Treat clusterStatus as optional in every consumer - absence is a valid degraded state
- Monitor instance-registry/broker health so degraded status responses are rare and visible
- Retry status queries after instance rollouts complete rather than during restarts
When it happens
Trigger: Multi-instance deployment where one instance's internal RPC is unreachable or timing out; microservices broker connectivity problems; instances mid-restart when the status is queried; heavy load causing the internal status broadcast to exceed its timeout.
Common situations: Kubernetes pods rolling-restarting; Rocket.Chat running with microservices (broker/DDP-streamer) and a flaky broker; single-instance dev setups with a broken instance registry
Related errors
- Failed to get apps status from node ${nodeID}
- This instance could not remove the ${item.info.name} app pac
- The user ${user.username} (${user._id}) does not have a vali
- The command is not currently disabled: "${cmd}"
- Invalid reaction
AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18).
Data as JSON: /api/errors/854bdef8ef4d4ba6.
Report an issue: GitHub.