phalcon/cphalcon · error · MissingAuthData
Auth data must be provided when using AEAD mode
Error message
Auth data must be provided when using AEAD mode
What it means
For AEAD modes (gcm/ccm) Crypt::encryptGcmCcm() requires associated authentication data: it reads $this->authData (set via setAuthData()) and throws MissingAuthData if it is empty. GCM/CCM distinguish 'additional authenticated data' from the message itself, and Phalcon mandates it rather than defaulting to empty, so encrypted payloads always carry an AEAD context.
Source
Thrown at phalcon/Encryption/Crypt.zep:895
string mode,
string padded,
string encryptKey,
string iv
) -> string {
var authData, authTag, authTagLength, cipher, encrypted;
let cipher = this->cipher,
authTag = "";
/**
* If the mode is "gcm" or "ccm" and auth data has been passed call it
* with that data
*/
if true === this->checkIsMode(["ccm", "gcm"], mode) {
let authData = this->authData;
if true === empty(authData) {
throw new MissingAuthData();
}
let authTag = this->authTag,
authTagLength = this->authTagLength;
let encrypted = openssl_encrypt(
padded,
cipher,
encryptKey,
OPENSSL_RAW_DATA,
iv,
authTag,
authData,
authTagLength
);
let this->authTag = authTag;
} else {View on GitHub (pinned to b7419de9cd)
Solutions
- Call $crypt->setAuthData($aad) before encrypting with a gcm/ccm cipher - use stable context such as the user id, record id, or app name so decryption can reproduce it exactly.
- The same auth data must be present (and identical) when decrypting - keep it alongside your configuration, not per-random values.
- If you have no meaningful AAD, prefer aes-256-cbc (with default HMAC signing) instead of passing dummy data - it sidesteps AEAD semantics entirely.
Example fix
// before
$crypt->setCipher('aes-256-gcm');
$crypt->setKey($key);
$token = $crypt->encrypt($payload); // MissingAuthData
// after
$crypt->setCipher('aes-256-gcm');
$crypt->setKey($key);
$crypt->setAuthData('user:' . $user->id);
$token = $crypt->encrypt($payload); Defensive patterns
Strategy: validation
Validate before calling
if ($crypt->getAuthData() === '') {
throw new \RuntimeException('AEAD cipher requires auth data - call setAuthData() before encrypt');
}
$cipherText = $crypt->encrypt($payload); Type guard
function isAeadReady(\Phalcon\Encryption\Crypt $crypt): bool
{
$mode = substr($crypt->getCipher(), -3); // 'gcm'/'ccm'
return !in_array($mode, ['gcm', 'ccm'], true) || '' !== $crypt->getAuthData();
} Try / catch
try {
$token = $crypt->encrypt($payload);
} catch (\Phalcon\Encryption\Crypt\Exception\MissingAuthData $e) {
throw new \RuntimeException('AEAD misconfigured: setAuthData() missing in Crypt setup', 0, $e);
} Prevention
- Encapsulate Crypt configuration in one factory: cipher + key + authData are set together, so gcm can never be half-configured.
- Use stable, reproducible auth data (user id, record id) so decrypt can recompute the same AAD.
- Prefer aes-256-cbc with default signing if you have no meaningful associated data.
When it happens
Trigger: setCipher('aes-256-gcm') followed by encrypt() without ever calling setAuthData('...'); or setAuthData('') (empty string counts as empty). Decrypting never throws this - only the encrypt path checks.
Common situations: Switching a service from aes-256-cbc to aes-256-gcm without adding the new required call; copying example code that predates the auth-data requirement; config defining auth_data only in some environments.
Related errors
- The auth tag length must be between 4 and 16 bytes.
- Decryption key cannot be empty
- Encryption key cannot be empty
- Could not encrypt data
- The provided input is too short for the selected cipher.
AI-assisted analysis of phalcon/cphalcon@b7419de9cd (2026-08-21).
Data as JSON: /api/errors/ab8823d803363d2a.
Report an issue: GitHub.