phalcon/cphalcon · error · Phalcon\Storage\Exceptions\ClusterConnectionFailed
Could not connect to the Redis Cluster server due to: {excep
Error message
Could not connect to the Redis Cluster server due to: {exception message} What it means
Phalcon\Storage\Adapter\RedisCluster::getAdapter() constructs \RedisCluster from the options (named cluster from redis.ini, or seed 'hosts', plus timeout, readTimeout, persistent, auth, context). Any Throwable from that constructor is wrapped in ClusterConnectionFailed with the underlying message appended and chained via getPrevious().
Source
Thrown at phalcon/Storage/Adapter/RedisCluster.zep:135
public function getAdapter() -> var
{
var connection, ex, options;
if (null === this->adapter) {
let options = this->options;
try {
let connection = new RedisService(
options["name"],
options["hosts"],
options["timeout"],
options["readTimeout"],
options["persistent"],
options["auth"],
options["context"]
);
} catch Throwable, ex {
throw new ClusterConnectionFailed(
"Could not connect to the Redis Cluster server due to: "
. ex->getMessage(),
0,
ex
);
}
connection->setOption(RedisConsts::OPT_PREFIX, this->prefix);
this->setSerializer(connection);
let this->adapter = connection;
}
return this->adapter;
}
/**
* Returns all the keys storedView on GitHub (pinned to b7419de9cd)
Solutions
- Verify every seed: redis-cli -h <host> -p <port> PING (cluster nodes must respond to CLUSTER INFO)
- Pass hosts as strings: ['hosts' => ['10.0.0.1:7000', '10.0.0.2:7001']]
- For named clusters set redis.clusters.seeds / redis.clusters.auth in redis.ini and use options ['name' => 'mycluster']
- Inspect getPrevious() for the real phpredis error and raise timeout/readTimeout if discovery is slow
Example fix
// before new RedisCluster($factory, ['hosts' => ['10.0.0.1']]); // missing port -> constructor throws // after new RedisCluster($factory, ['hosts' => ['10.0.0.1:7000', '10.0.0.2:7001']]);
Defensive patterns
Strategy: try-catch
Validate before calling
// fail fast at boot instead of the first cache hit
foreach ($options['hosts'] as $host) {
[$h, $p] = array_pad(explode(':', $host, 2), 2, '6379');
$sock = @fsockopen($h, (int) $p, $errno, $errstr, 0.5);
if ($sock === false) {
throw new RuntimeException("Cluster seed {$host} unreachable: {$errstr}");
}
fclose($sock);
} Try / catch
try {
$cluster->getAdapter();
} catch (\Phalcon\Storage\Exceptions\ClusterConnectionFailed $e) {
// the underlying phpredis error is in getMessage() and getPrevious()
$logger->error('RedisCluster connect failed: ' . $e->getMessage(), ['previous' => $e->getPrevious()]);
throw $e;
} Prevention
- Format hosts strictly as 'host:port' strings; validate in config tests
- For named clusters keep redis.ini seeds in the same deploy unit as the app
- Warm the cluster connection at boot so outages surface in health checks, not user requests
When it happens
Trigger: Seed hosts unreachable or ports wrong; 'hosts' entries not formatted as 'host:port' strings; using 'name' for a cluster not defined in redis.ini (redis.clusters.seeds missing); cluster auth failure; timeout too low for cluster discovery; pointing the RedisCluster adapter at a single non-cluster Redis.
Common situations: First cache call after a cluster outage or config change; typos in host strings; forgetting redis.ini seeds for named clusters; local dev against plain Redis while the config says cluster.
Related errors
- {underlying exception message}
- Could not connect to the Redis server [%s:%s]
- Failed to authenticate with the Redis server
- Redis server selected database failed
- Cannot set Memcached client options
AI-assisted analysis of phalcon/cphalcon@b7419de9cd (2026-08-21).
Data as JSON: /api/errors/1efb3a9a1abd4162.
Report an issue: GitHub.