laravel/framework · critical · RuntimeException

Unsupported cipher or incorrect key length. Supported…

Error message

Unsupported cipher or incorrect key length. Supported ciphers are: {$ciphers}.

What it means

Encrypter::__construct validates the key+cipher pair via Encrypter::supported(), which checks that the cipher is one of aes-128-cbc / aes-256-cbc / aes-128-gcm / aes-256-gcm AND that mb_strlen($key) matches the required byte size (16 or 32). If either fails, supported() returns false and the constructor throws. This is usually hit at application boot when APP_KEY and the configured cipher disagree.

Solutions

  1. Regenerate the key with the matching cipher: php artisan key:generate --cipher=aes-256-cbc (or whichever your config uses).
  2. Make config('app.cipher') match the key length: 16-byte key → aes-128-*, 32-byte key → aes-256-*.
  3. Verify the key is the raw decoded bytes the Encrypter expects (Laravel's APP_KEY is base64-Encoded, decoded automatically by KeyGuesser/the framework).
  4. If constructing the Encrypter manually, ensure mb_strlen($key, '8bit') equals 16 or 32 before calling new Encrypter($key, $cipher).

Example fix

// before
// .env: APP_KEY=base64:shortKey     (decodes to 16 bytes)
// config/app.php: 'cipher' => 'aes-256-cbc',

// after (align cipher to key)
// .env: APP_KEY=base64:shortKey
// config/app.php: 'cipher' => 'aes-128-cbc',
// or regenerate a 32-byte key
// $ php artisan key:generate --cipher=aes-256-cbc
Defensive patterns

Strategy: validation

Validate before calling

use Illuminate\Encryption\Encrypter;

$key = (string) config('app.key');
$cipher = config('app.cipher', 'aes-128-cbc');

if (! Encrypter::supported($key, $cipher)) {
    throw new RuntimeException('APP_KEY length does not match cipher '.$cipher);
}

new Encrypter($key, $cipher);

Type guard

function keyMatchesCipher(string $key, string $cipher): bool {
    return \Illuminate\Encryption\Encrypter::supported($key, $cipher);
}

Prevention

When it happens

Trigger: Booting the app with APP_KEY set to a value whose length does not match the configured cipher (e.g. a 16-byte key with 'aes-256-cbc'); setting an invalid cipher string in config/app.php; passing a custom key/cipher to new Encrypter() that violates the size map.

Common situations: Generating APP_KEY on one project (32-char base64 → 32 raw bytes after decode for aes-256-cbc) and copying it to a project configured for aes-128-cbc; mis-typing the cipher; older Laravel cipher 'aes-256-cbc' vs newer 'aes-128-gcm' mismatch after an upgrade; using a raw hex key of the wrong length.

Related errors


AI-assisted analysis of laravel/framework@e0f6eb3518 (2026-08-11). Data as JSON: /api/errors/04febb9eb3335147. Report an issue: GitHub.

Appendix: 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 e0f6eb3518)