laravel/framework · error · BroadcastException

Redis error: .

Error message

Redis error: %s.

What it means

RedisBroadcaster::broadcast executes a Lua script over the Redis connection to fan a payload out to multiple channels. If the Redis connection raises a ConnectionException or RedisException (from the predis/predis or phpredis extension), it is wrapped into a BroadcastException with the original Redis error message. This isolates transport-level Redis failures behind Laravel's broadcasting abstraction.

Solutions

  1. Verify REDIS_HOST, REDIS_PORT, REDIS_PASSWORD, and the 'database' cache/queue/broadcast connection block in config/database.php match the Redis server.
  2. For Redis Cluster, ensure 'cluster' => true (or use 'redis_clusters' / 'clusters' options) so the randomClusterNodeConnection branch is exercised instead of failing on a single-node assumption.
  3. Catch \Illuminate\Broadcasting\BroadcastException and inspect the chained Redis exception via getPrevious() to triage OOM vs auth vs network.
  4. Check Redis server logs for 'OOM command not allowed' or 'NOSCRIPT' errors if the EVAL call repeatedly fails.

Example fix

// before
broadcast(new OrderShipped($order));

// after
use Illuminate\Broadcasting\BroadcastException;

try {
    broadcast(new OrderShipped($order));
} catch (BroadcastException $e) {
    $redisCause = $e->getPrevious();
    logger()->error('Redis broadcast failed', [
        'message' => $redisCause?->getMessage(),
        'order_id' => $order->id,
    ]);
    throw $e;
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Validate Redis connectivity before broadcasting in long-running processes
$redis = Cache::store('redis')->getRedis();
if (! $redis->ping()) {
    throw new \RuntimeException('Redis unreachable; cannot broadcast.');
}

Try / catch

use Illuminate\Broadcasting\BroadcastException;

try {
    broadcast($event);
} catch (BroadcastException $e) {
    $cause = $e->getPrevious();
    if ($cause instanceof \Redis\ConnectionException
        || $cause instanceof \Predis\Connection\ConnectionException) {
        // network-level failure: queue for retry
        dispatch(new RetryBroadcast($event))->delay(now()->addSeconds(5));
        return;
    }
    throw $e;
}

Prevention

When it happens

Trigger: Calling broadcast()/event() while the configured REDIS_HOST/REDIS_PORT is unreachable, REDIS_PASSWORD is wrong, the Redis server is maxed on memory (OOM during EVAL), or the phpredis/predis client times out on a slow cluster node. Specifically occurs in the broadcastMultipleChannelsScript eval path.

Common situations: REDIS_PASSWORD mismatch between Laravel and the Redis server (common on managed Redis like Upstash/Redis Cloud after rotation). Using a Redis Cluster URL but config/database.php has 'cluster' => false. Lua script blocked by Redis 'no scripts' configuration (e.g., AWS ElastiCache with parameter group restrictions). Network partitions to Redis during high traffic.

Related errors


AI-assisted analysis of laravel/framework@e0f6eb3518 (2026-08-11). Data as JSON: /api/errors/ea3ae5a84264d771. Report an issue: GitHub.

Appendix: source

Thrown at src/Illuminate/Broadcasting/Broadcasters/RedisBroadcaster.php:157

                    $connection->client()->getClientBy('slot', mt_rand(0, 16383))
                );

                if ($events = $connection->getEventDispatcher()) {
                    $randomClusterNodeConnection->setEventDispatcher($events);
                }

                $randomClusterNodeConnection->eval(
                    $this->broadcastMultipleChannelsScript(),
                    0, $payload, ...$this->formatChannels($channels)
                );
            } else {
                $connection->eval(
                    $this->broadcastMultipleChannelsScript(),
                    0, $payload, ...$this->formatChannels($channels)
                );
            }
        } catch (ConnectionException|RedisException $e) {
            throw new BroadcastException(
                sprintf('Redis error: %s.', $e->getMessage())
            );
        }
    }

    /**
     * Get the Lua script for broadcasting to multiple channels.
     *
     * ARGV[1] - The payload
     * ARGV[2...] - The channels
     *
     * @return string
     */
    protected function broadcastMultipleChannelsScript()
    {
        return <<<'LUA'
for i = 2, #ARGV do
  redis.call('publish', ARGV[i], ARGV[1])

View on GitHub (pinned to e0f6eb3518)