nestjs/nest · warning
RMQ broker has blocked the connection (flow control). Reason
Error message
RMQ broker has blocked the connection (flow control). Reason: ${reason} What it means
RabbitMQ blocks publishing connections when the node raises a resource alarm (memory above vm_memory_high_watermark or free disk below disk_free_limit). The amqp-connection-manager emits a BLOCKED event carrying the broker's reason; ClientRMQ's registerBlockedListener records it, pushes RmqStatus.BLOCKED into the client's status stream and logs this warning. While blocked, the broker holds back all publishes on that connection, so client.send()/emit() calls silently stall until the matching UNBLOCKED event.
Source
Thrown at packages/microservices/client/client-rmq.ts:311
if (this.isInitialConnect) {
this.isInitialConnect = false;
if (!this.channel) {
this.connectionPromise = this.createChannel();
}
} else {
this.connectionPromise = Promise.resolve();
}
});
}
public registerBlockedListener(client: AmqpConnectionManager): void {
client.addListener(
RmqEventsMap.BLOCKED,
({ reason }: { reason: string }) => {
this._status$.next(RmqStatus.BLOCKED);
this.logger.warn(BLOCKED_RMQ_MESSAGE(reason));
},
);
}
public registerUnblockedListener(client: AmqpConnectionManager): void {
client.addListener(RmqEventsMap.UNBLOCKED, () => {
this._status$.next(RmqStatus.UNBLOCKED);
this.logger.log(UNBLOCKED_RMQ_MESSAGE);
});
}
public on<
EventKey extends keyof RmqEvents = keyof RmqEvents,
EventCallback extends RmqEvents[EventKey] = RmqEvents[EventKey],
>(event: EventKey, callback: EventCallback) {
if (this.client) {
this.client.addListener(event, callback);
} else {View on GitHub (pinned to dd75d7bd8c)
Solutions
- Clear the alarm on the broker: check `rabbitmqctl status` (alarms section), free disk above disk_free_limit, and give the node more memory or raise vm_memory_high_watermark (e.g. rabbitmq.conf: vm_memory_high_watermark.relative = 0.6, disk_free_limit.absolute = 2GB).
- Fix the backpressure root cause: scale up consumers and bound prefetch so queues drain instead of growing into the alarm.
- Subscribe to the client's `client.status` observable and pause/throttle publishing while it emits RmqStatus.BLOCKED, resuming on UNBLOCKED/CONNECTED.
- Reduce publish rate or batch size at the producer and enable publisher confirms so stalled publishes are detectable.
Example fix
// before: keeps bursting through broker flow control
setInterval(() => client.emit('telemetry', sample()), 1);
// after: buffer while the broker has blocked the connection
import { RmqStatus } from '@nestjs/microservices';
let blocked = false;
const buffer: any[] = [];
client.status.subscribe((status) => {
const wasBlocked = blocked;
blocked = status === RmqStatus.BLOCKED;
if (wasBlocked && !blocked) {
while (buffer.length) client.emit('telemetry', buffer.shift());
}
});
function publish(msg: any) {
blocked ? buffer.push(msg) : client.emit('telemetry', msg);
} Defensive patterns
Strategy: fallback
Validate before calling
import { firstValueFrom, filter } from 'rxjs';
import { RmqStatus } from '@nestjs/microservices';
// don't burst while the broker has the connection blocked
async function waitForUnblocked(client: ClientRMQ) {
const status = await firstValueFrom(client.status);
if (status === RmqStatus.BLOCKED) {
await firstValueFrom(
client.status.pipe(filter((s) => s === RmqStatus.UNBLOCKED || s === RmqStatus.CONNECTED)),
);
}
} Prevention
- Set vm_memory_high_watermark and disk_free_limit with real headroom for the broker container/node
- Bound consumer lag: scale consumers and use finite prefetch so queues don't grow into memory alarms
- Subscribe to client.status and pause/throttle publishing on RmqStatus.BLOCKED instead of pushing blindly
- Alert on broker alarms (rabbitmq-diagnostics alarms) and on BLOCKED client status
- Load-test publish throughput against a broker holding production-sized queues
When it happens
Trigger: A ClientRMQ (ClientsModule.register / ClientProxyFactory with Transport.RMQ) publishing while the broker trips a memory or disk alarm — the broker sends connection.blocked with reason 'memory' or 'disk'. Commonly caused by vm_memory_high_watermark breach, disk_free_limit breach, or a node-wide alarm raised by another noisy client on the same broker node.
Common situations: RabbitMQ in docker-compose/Kubernetes with tight memory limits; producers outpacing consumers so queues grow into the memory alarm; large payloads (media, batch uploads); shared brokers where another team's flood blocks every publishing connection including yours; broker node disk filling up.
Related errors
- RMQ broker has blocked the connection (flow control). Reason
- An unsupported message was received. It has been negative ac
- An unsupported event was received. It has been negative ackn
AI-assisted analysis of nestjs/nest@dd75d7bd8c (2026-08-21).
Data as JSON: /api/errors/a82c1889d951481b.
Report an issue: GitHub.