php-amqplib/php-amqplib · critical · AMQPConnectionClosedException
Broken pipe or closed connection
Error message
Broken pipe or closed connection
What it means
StreamIO::read() detects that the socket is no longer a valid resource or has hit EOF before the requested bytes could be read. The connection is closed and AMQPConnectionClosedException('Broken pipe or closed connection') is thrown, signaling the AMQP connection is dead.
Solutions
- Check broker logs and connectivity (is RabbitMQ up? correct host/port/firewall rules?)
- Configure heartbeats so dead connections are detected and handled predictably (heartbeat in AMQPConnectionConfig)
- Wrap consumption/publishing in a try-catch for AMQPConnectionClosedException and reconnect with backoff
- Investigate why the server closed: heartbeat timeouts, connection_limits, per-user channel limits, or idle LB timeouts
Example fix
// before
$msg = $channel->basic_get($queue); // throws on dead connection
// after
try {
$msg = $channel->basic_get($queue);
} catch (AMQPConnectionClosedException $e) {
$connection = reconnectWithBackoff();
$channel = $connection->channel();
$msg = $channel->basic_get($queue);
} Defensive patterns
Strategy: try-catch
Validate before calling
// before consuming/publishing, verify the broker is reachable
if (@fsockopen($host, $port, $errno, $errstr, 2) === false) {
throw new \RuntimeException("Broker unreachable: $errstr ($errno)");
} Try / catch
try {
$channel->basic_consume($queue, ...);
} catch (PhpAmqpLib\Exception\AMQPConnectionClosedException $e) {
$this->connection = $this->factory->createConnectionWithBackoff();
$this->channel = $this->connection->channel();
$this->resubscribe();
} Prevention
- Enable heartbeats (e.g. 15-60s) so dead connections are detected promptly
- Keep read/write timeouts realistic for your operations
- Supervise long-running consumers with reconnect + resubscribe logic
- Monitor broker logs for connection closes (timeouts, limits, alarms)
When it happens
Trigger: Broker closed the TCP connection or the network dropped while StreamIO::read() was awaiting len bytes; is_resource($this->sock) fails or feof($this->sock) is true inside the read loop.
Common situations: RabbitMQ broker restart/crash, heartbeat timeout closing an idle connection, network interruption, firewall/LB killing idle TCP sessions, consumer reading after channel/connection was closed server-side.
Understand the failure class
- Connection failures: ECONNREFUSED, ECONNRESET, and friends — why connections get refused, reset, or dropped.
Related errors
AI-assisted analysis of php-amqplib/php-amqplib@381b6f7c60 (2026-09-20).
Data as JSON: /api/errors/cf18b0d50760febd.
Report an issue: GitHub.
Appendix: source
Thrown at PhpAmqpLib/Wire/IO/StreamIO.php:187
}
/**
* @inheritdoc
*/
public function read($len)
{
$this->check_heartbeat();
list($timeout_sec, $timeout_uSec) = MiscHelper::splitSecondsMicroseconds($this->read_timeout);
$read_start = microtime(true);
$read = 0;
$data = '';
while ($read < $len) {
if (!is_resource($this->sock) || feof($this->sock)) {
$this->close();
throw new AMQPConnectionClosedException('Broken pipe or closed connection');
}
$this->setErrorHandler();
try {
$buffer = fread($this->sock, ($len - $read));
$this->throwOnError();
} catch (\ErrorException $e) {
throw new AMQPDataReadException($e->getMessage(), $e->getCode(), $e->getPrevious());
} finally {
$this->restoreErrorHandler();
}
if ($buffer === false) {
throw new AMQPDataReadException('Error receiving data');
}
if ($buffer === '') {
$read_now = microtime(true);View on GitHub (pinned to 381b6f7c60)