phacility/phabricator · error · Exception
Keyring specifies an invalid key ("%s"): key material should
Error message
Keyring specifies an invalid key ("%s"): key material should be 32 bytes (256 bits) but has length %s. What it means
After strict base64 decoding, key material for an aes-256-cbc key must be exactly 32 bytes (256 bits); the validator measures strlen() and reports the actual length when it differs. This guarantees the material matches the AES-256 key size the storage format passes to openssl_decrypt/encrypt.
Source
Thrown at src/applications/files/keyring/PhabricatorKeyringConfigOptionType.php:84
pht(
'Keyring is configured with a "%s" key, but the PHP OpenSSL '.
'extension is not installed. Install the OpenSSL extension '.
'to enable encryption.',
$type));
}
$material = $spec['material.base64'];
$material = base64_decode($material, true);
if ($material === false) {
throw new Exception(
pht(
'Keyring specifies an invalid key ("%s"): key material '.
'should be base64 encoded.',
$name));
}
if (strlen($material) != 32) {
throw new Exception(
pht(
'Keyring specifies an invalid key ("%s"): key material '.
'should be 32 bytes (256 bits) but has length %s.',
$name,
new PhutilNumber(strlen($material))));
}
break;
default:
throw new Exception(
pht(
'Keyring configuration is invalid: it describes a key with '.
'type "%s", but this type is unknown.',
$type));
}
}
if (count($defaults) > 1) {
throw new Exception(View on GitHub (pinned to 5720a38cfe)
Solutions
- Regenerate the key as exactly 32 random bytes: php -r 'echo base64_encode(random_bytes(32)), PHP_EOL;'
- Verify the decoded length: php -r 'echo strlen(base64_decode("<VALUE>", true));' must print 32
- If you intended a passphrase-derived key, that is not supported — use random key material
Example fix
# before: 16-byte key "material.base64": "MTIzNDU2Nzg5MGFiY2RlZg==" # decodes to 16 bytes # after: 32-byte key php -r 'echo base64_encode(random_bytes(32)), PHP_EOL;' # paste result "material.base64": "oPHAD/7m2Xy0Zl+Bq1c8Yk0PM4YfNpLrS4jEwVnN0F0="
Defensive patterns
Strategy: validation
Validate before calling
$decoded = base64_decode($material, true);
if ($decoded !== false && strlen($decoded) !== 32) {
// Key "{$name}" is ".strlen($decoded)." bytes; AES-256 requires exactly 32.
} Prevention
- Always generate 32 random bytes: php -r 'echo base64_encode(random_bytes(32));'
- Verify length after any transformation pipeline: strlen(base64_decode($v, true)) === 32
- Do not reuse keys cut for AES-128 or derived from passphrases
When it happens
Trigger: Base64 of a 16-byte (AES-128) or 24-byte key; base64 of a human passphrase instead of 32 random bytes; double-base64-encoded material decoding to a non-32-byte intermediate; base64 of a hex string (64 characters).
Common situations: Reusing a key generated for another cipher; typing a passphrase and base64-ing it; material passing through a pipeline that encodes twice.
Related errors
- Keyring configuration is invalid: it describes a key with ty
- No AES256 key is specified in the keyring as a default encry
- No key "%s" exists in keyring.
- Keyring configuration is not valid: value must be a list of
- Keyring configuration is not valid: each entry in the list m
AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21).
Data as JSON: /api/errors/1f3d51fb31265301.
Report an issue: GitHub.