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

  1. Check broker logs and connectivity (is RabbitMQ up? correct host/port/firewall rules?)
  2. Configure heartbeats so dead connections are detected and handled predictably (heartbeat in AMQPConnectionConfig)
  3. Wrap consumption/publishing in a try-catch for AMQPConnectionClosedException and reconnect with backoff
  4. 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

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

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)