phalcon/cphalcon · error · Phalcon\Http\Cookie\Exceptions\CryptInterfaceRequired

A dependency which implements CryptInterface is required to

Error message

A dependency which implements CryptInterface is required to use encryption

What it means

After resolving container->getShared('crypt'), Http\Cookie verifies the returned service is an object before casting it to CryptInterface. A 'crypt' service defined as a non-object — a string (for example the key name), an array, or a definition that returns a scalar — throws CryptInterfaceRequired.

Source

Thrown at phalcon/Http/Cookie.zep:214

        let container = null,
            name = this->name;

        if this->isRead === false {
            if !fetch value, _COOKIE[name] {
                return defaultValue;
            }

            if this->useEncryption {
                let container = <DiInterface> this->container;

                if container === null {
                    throw new CryptServiceUnavailable();
                }

                let crypt = <CryptInterface> container->getShared("crypt");

                if unlikely typeof crypt != "object" {
                    throw new CryptInterfaceRequired();
                }

                /**
                 * Verify the cookie's value if the sign key was set
                 */
                let signKey = this->signKey;

                if typeof signKey === "string" {
                    /**
                     * Decrypt the value also decoding it with base64
                     */
                    let decryptedValue = crypt->decryptBase64(
                        value,
                        signKey
                    );
                } else {
                    /**
                     * Decrypt the value also decoding it with base64

View on GitHub (pinned to b7419de9cd)

Solutions

  1. Register a real service: $di->setShared('crypt', fn() => new \Phalcon\Crypt\Crypt())
  2. Verify resolution: assert($di->getShared('crypt') instanceof \Phalcon\Encryption\Crypt\CryptInterface)
  3. Fix custom container definitions so getShared('crypt') returns a resolved object

Example fix

// before
$di->set('crypt', function () {
    return $this->getConfig()->path('security.cryptKey'); // returns a string
});

// after
$di->setShared('crypt', function () {
    $crypt = new \Phalcon\Encryption\Crypt\Crypt();
    $crypt->setKey($this->getConfig()->path('security.cryptKey'));

    return $crypt;
});
Defensive patterns

Strategy: validation

Validate before calling

$crypt = Di::getDefault()?->getShared('crypt');

if (!is_object($crypt) || !($crypt instanceof \Phalcon\Encryption\Crypt\CryptInterface)) {
    throw new \RuntimeException(
        "The 'crypt' service must resolve to an object implementing CryptInterface"
    );
}

$value = $cookie->getValue();

Type guard

/** @param mixed $service */
function isCryptService($service): bool
{
    return is_object($service)
        && $service instanceof \Phalcon\Encryption\Crypt\CryptInterface;
}

Try / catch

try {
    $value = $cookie->getValue();
} catch (\Phalcon\Http\Cookie\Exceptions\CryptInterfaceRequired $e) {
    // the DI definition is wrong; surface it loudly rather than disabling encryption
    $logger->critical($e->getMessage());
    throw $e;
}

Prevention

When it happens

Trigger: The container defines 'crypt' as a plain string (a config value or key name) instead of a Crypt instance; a factory closure returns a scalar; the service resolves to null because the definition was unset or misnamed.

Common situations: Config-driven DI setups where 'crypt' is accidentally bound to the encryption key rather than the service; custom containers whose getShared() returns the raw definition instead of resolving it; copying config between projects with different service definitions.

Related errors


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