phalcon/cphalcon · error · Phalcon\Storage\Exceptions\AuthenticationFailed

Failed to authenticate with the Redis server

Error message

Failed to authenticate with the Redis server

What it means

During lazy connect (first cache call), after checkConnect() succeeds, Phalcon\Storage\Adapter\Redis calls Redis::auth() with options['auth'] (a password string, or ['user' => ..., 'password' => ...] for Redis 6 ACL). If auth() returns false or throws, Phalcon throws AuthenticationFailed with no detail payload.

Source

Thrown at phalcon/Storage/Adapter/Redis.zep:392

    /**
     * @param RedisService $connection
     *
     * @throws AuthenticationFailed
     */
    private function checkAuth(<RedisService> connection) -> <static>
    {
        var auth, error;

        let auth = this->options["auth"];

        try {
            let error = (true !== empty(auth) && true !== connection->auth(auth));
        } catch BaseException {
            let error = true;
        }

        if error {
            throw new AuthenticationFailed();
        }

        return this;
    }

    /**
     * @throws ConnectionFailed
     */
    private function checkConnect(<RedisService> connection) -> <static>
    {
        var auth, connectionOptions, ex, host, method, options, parameter,
            persistentId, port, retryInterval, readTimeout, result, ssl, timeout;

        let options       = this->options,
            host          = options["host"],
            port          = options["port"],
            timeout       = options["timeout"],
            retryInterval = options["retryInterval"],

View on GitHub (pinned to b7419de9cd)

Solutions

  1. Verify credentials out of band from the same host: redis-cli -h <host> -p <port> --user <user> -a <password> PING
  2. For Redis 6+ ACL pass an array: ['auth' => ['user' => 'app', 'password' => 'secret']]
  3. Ensure the ACL user has connection and key permissions on the selected index ('index' option)
  4. Drop the 'auth' option entirely if the server has no authentication

Example fix

// before
new Redis($factory, ['auth' => 'app:secret']); // treated as one password -> AuthenticationFailed

// after (Redis 6 ACL)
new Redis($factory, ['auth' => ['user' => 'app', 'password' => 'secret']]);
Defensive patterns

Strategy: try-catch

Validate before calling

// fail fast at boot with a cheap round-trip before serving traffic
try {
    $adapter->getAdapter(); // triggers connect + auth + select
} catch (\Phalcon\Storage\Exceptions\AuthenticationFailed $e) {
    $logger->critical('Redis auth failed — check the auth option and ACL user');
}

Try / catch

try {
    $value = $cache->get($key);
} catch (\Phalcon\Storage\Exceptions\AuthenticationFailed $e) {
    // wrong password or ACL format — do not retry, page a human
    $logger->alert('Redis credentials rejected');
    throw new ServiceUnavailableException('Cache unavailable', 0, $e);
}

Prevention

When it happens

Trigger: Wrong password in the 'auth' option; Redis 6+ ACL user with missing permissions but credentials passed in a format phpredis cannot map to AUTH/HELLO; requirepass/ACL changed after deploy; auth string accidentally containing the 'user:password' form while the server has no ACL user (it is then treated as one password).

Common situations: Credential rotation without updating the cache config; empty or wrong env var in one environment; switching from single-password Redis to ACL users without moving from string auth to the array form.

Understand the failure class

Related errors


AI-assisted analysis of phalcon/cphalcon@b7419de9cd (2026-08-21). Data as JSON: /api/errors/332734e083b35d3b. Report an issue: GitHub.