{"record":{"id":"60508a3bc058f7e6","repo":"phalcon/cphalcon","slug":"decryption-key-cannot-be-empty","errorCode":null,"errorMessage":"Decryption key cannot be empty","messagePattern":"Decryption key cannot be empty","errorType":"exception","errorClass":"EmptyDecryptionKey","httpStatus":null,"severity":"error","filePath":"phalcon/Encryption/Crypt.zep","lineNumber":230,"sourceCode":"     * @param string|null $key\n     *\n     * @return string\n     * @throws Exception\n     * @throws InvalidDecryptLength\n     * @throws Mismatch\n     */\n    public function decrypt(string input, string key = null) -> string\n    {\n        var blockSize, cipher, cipherText, decrypted, decryptKey, digest,\n            hashAlgorithm, hashLength, iv, ivLength, mode;\n\n        let decryptKey = this->key;\n        if true !== empty(key) {\n            let decryptKey = key;\n        }\n\n        if true === empty(decryptKey) {\n            throw new EmptyDecryptionKey();\n        }\n\n        let cipher   = this->cipher,\n            ivLength = this->ivLength;\n\n        this->checkCipherHashIsAvailable(cipher, \"cipher\");\n\n        if true !== this->isValidDecryptLength(input) {\n            throw new InvalidDecryptLength();\n        }\n\n        let mode      = this->getMode(),\n            blockSize = this->getBlockSize(mode),\n            iv        = mb_substr(input, 0, ivLength, \"8bit\");\n\n        /**\n         * Check if we have chosen signing and use the hash\n         */","sourceCodeStart":212,"sourceCodeEnd":248,"githubUrl":"https://github.com/phalcon/cphalcon/blob/b7419de9cd0a8a3f48441ead84c9f8415d463e25/phalcon/Encryption/Crypt.zep#L212-L248","documentation":"Crypt::decrypt() requires a key: it uses the key passed as the second argument, falling back to the key set earlier with setKey(). If both are absent or empty, it throws EmptyDecryptionKey before touching any ciphertext. This is a configuration error, not a data error.","triggerScenarios":"Creating $crypt = new Crypt() and calling decrypt($ciphertext) without ever calling setKey(), or calling setKey('') / setKey(null-ish) and decrypt() without the second argument. Also when a shared Crypt instance is built from config and the config key is missing/empty in one environment.","commonSituations":"Environment-specific config where the encryption key env var (e.g. APP_KEY) is defined in production but not locally or in CI; instantiating Crypt inline in a helper instead of pulling the configured instance from the DI container; trimming/rotating keys and accidentally storing an empty string.","solutions":["Call $crypt->setKey($key) once at setup (DI definition) with a cryptographically random key of the exact length your cipher needs (e.g. 32 bytes for aes-256).","Or pass the key per call: $crypt->decrypt($payload, $key).","Load the key from a single env/config source and fail application boot if it is empty, so misconfiguration surfaces at startup rather than mid-request.","Ensure the SAME key is used for encrypt and decrypt (see Mismatch otherwise)."],"exampleFix":"// before\n$crypt = new \\Phalcon\\Encryption\\Crypt();\n$plain = $crypt->decrypt($token);   // no key ever set\n\n// after\n$crypt = new \\Phalcon\\Encryption\\Crypt();\n$crypt->setKey(getenv('APP_ENCRYPTION_KEY'));  // validated non-empty at boot\n$plain = $crypt->decrypt($token);","handlingStrategy":"validation","validationCode":"$key = $config->path('encryption.key');\nif (empty($key)) {\n    throw new \\RuntimeException('Encryption key missing - check encryption.key config');\n}\n$crypt->setKey($key);\n// only now call decrypt()","typeGuard":"function hasCryptKey(\\Phalcon\\Encryption\\Crypt $crypt): bool\n{\n    return '' !== $crypt->getKey();\n}","tryCatchPattern":"try {\n    $plain = $crypt->decrypt($cipherText);\n} catch (\\Phalcon\\Encryption\\Crypt\\Exception\\EmptyDecryptionKey $e) {\n    // configuration bug - do not retry; fail fast with context\n    throw new \\RuntimeException('Crypt used without a key - check DI setup', 0, $e);\n}","preventionTips":["Configure the key once in the DI definition and assert non-empty at boot.","Fail application startup when the key env var is missing rather than letting first decrypt blow up.","Keep a health check that verifies getKey() is non-empty in production."],"tags":["phalcon","crypt","encryption","key-management","configuration"],"backgroundTag":"empty-encryption-key","analyzedSha":"b7419de9cd0a8a3f48441ead84c9f8415d463e25","analyzedAt":"2026-08-21T06:21:18.811Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}