laravel/framework · critical · RuntimeException
Unsupported cipher or incorrect key length. Supported cipher
Error message
Unsupported cipher or incorrect key length. Supported ciphers are: {$ciphers}. What it means
Encrypter constructor throws RuntimeException when the (key, cipher) pair fails static::supported(). supported() checks that the cipher is one of aes-128-cbc/aes-256-cbc/aes-128-gcm/aes-256-gcm AND that the raw key length matches (16 or 32 bytes). The message lists the valid ciphers. A misconfigured APP_KEY or cipher is the canonical cause.
Source
Thrown at src/Illuminate/Encryption/Encrypter.php:61
'aes-256-gcm' => ['size' => 32, 'aead' => true],
];
/**
* Create a new encrypter instance.
*
* @param string $key
* @param string $cipher
*
* @throws \RuntimeException
*/
public function __construct(#[\SensitiveParameter] $key, $cipher = 'aes-128-cbc')
{
$key = (string) $key;
if (! static::supported($key, $cipher)) {
$ciphers = implode(', ', array_keys(self::$supportedCiphers));
throw new RuntimeException("Unsupported cipher or incorrect key length. Supported ciphers are: {$ciphers}.");
}
$this->key = $key;
$this->cipher = $cipher;
}
/**
* Determine if the given key and cipher combination is valid.
*
* @param string $key
* @param string $cipher
* @return bool
*/
public static function supported(#[\SensitiveParameter] $key, $cipher)
{
if (! isset(self::$supportedCiphers[strtolower($cipher)])) {
return false;
}View on GitHub (pinned to bd6b5437e6)
Solutions
- Regenerate the key for the chosen cipher: php artisan key:generate (it base64-encodes 32 random bytes, matching aes-256-cbc).
- Ensure config('app.cipher') matches the key size: aes-128-* needs a 16-byte key, aes-256-* needs 32 bytes.
- If you set a raw key, prefix with 'base64:' and confirm base64_decode yields 16 or 32 bytes.
- When calling previousKeys(), pass only keys whose length matches the current cipher.
Example fix
// before — key/cipher mismatch // .env: APP_KEY=abc123 (too short) // config/app.php: 'cipher' => 'aes-256-gcm', // after // shell: // $ php artisan key:generate // Application key set successfully. // .env: APP_KEY=base64:aaaaBBBB....(== 44 chars base64 => 32 raw bytes) // config/app.php: 'cipher' => 'aes-256-gcm',
Defensive patterns
Strategy: validation
Validate before calling
use Illuminate\Encryption\Encrypter;
$key = config('app.key');
$cipher = config('app.cipher');
if (! Encrypter::supported($key, $cipher)) {
throw new \RuntimeException('APP_KEY / cipher mismatch — run php artisan key:generate');
} Type guard
function appKeyValidForCipher(): bool
{
return \Illuminate\Encryption\Encrypter::supported(config('app.key'), config('app.cipher'));
} Prevention
- Always generate keys with php artisan key:generate (correct length, base64-encoded).
- Keep APP_KEY and cipher consistent across all environments.
- Validate previous_keys lengths against the configured cipher.
When it happens
Trigger: Instantiating new Encrypter($key, $cipher) or booting the EncryptionServiceProvider when APP_KEY length does not match the configured cipher (e.g. APP_KEY is a 32-char ASCII string but cipher is aes-128-cbc, or APP_KEY is empty/malformed). Note: Laravel's 'base64:' prefix decodes to raw bytes; a plain hex/ascii key without prefix is taken literally.
Common situations: Fresh deploy missing APP_KEY; key generated for one cipher then cipher changed in config/app.php; copying .env between projects; truncated APP_KEY; using a hex string instead of base64-encoded random bytes; setting previous_keys to a wrong-length key.
Related errors
- Could not encrypt the data.
- The MAC is invalid.
- Unable to use tag because the cipher algorithm does not supp
- Callback must be a callable, callback array, or a 'Class@met
- Auth guard [{$name}] is not defined.
AI-assisted analysis of laravel/framework@bd6b5437e6 (2026-08-06).
Data as JSON: /data/errors/04febb9eb3335147.json.
Report an issue: GitHub.