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 base64View on GitHub (pinned to b7419de9cd)
Solutions
- Register a real service: $di->setShared('crypt', fn() => new \Phalcon\Crypt\Crypt())
- Verify resolution: assert($di->getShared('crypt') instanceof \Phalcon\Encryption\Crypt\CryptInterface)
- 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
- Register crypt as a setShared service returning a Crypt instance, never a key string
- Add a container smoke test asserting getShared('crypt') instanceof CryptInterface
- Never disable encryption to work around this error — fix the service definition
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
- A dependency injection container is required to access the '
- A dependency injection container is required to access the '
- Service '{name}' not registered
- Argument at position {} must have a type
- Service '{}' is required in parameter on position {}
AI-assisted analysis of phalcon/cphalcon@b7419de9cd (2026-08-21).
Data as JSON: /api/errors/157ede1ebef5e96a.
Report an issue: GitHub.