{"record":{"id":"77cb7ea12447b492","repo":"laravel/framework","slug":"the-mac-is-invalid","errorCode":null,"errorMessage":"The MAC is invalid.","messagePattern":"The MAC is invalid\\.","errorType":"exception","errorClass":"DecryptException","httpStatus":null,"severity":"critical","filePath":"src/Illuminate/Encryption/Encrypter.php","lineNumber":191,"sourceCode":"\n                if ($validMac && $validKey === null) {\n                    $validKey = $key;\n                }\n\n                continue;\n            }\n\n            $decrypted = \\openssl_decrypt(\n                $payload['value'], strtolower($this->cipher), $key, 0, $iv, $tag ?? ''\n            );\n\n            if ($decrypted !== false) {\n                break;\n            }\n        }\n\n        if ($this->shouldValidateMac() && $validKey === null) {\n            throw new DecryptException('The MAC is invalid.');\n        }\n\n        if ($this->shouldValidateMac()) {\n            $decrypted = \\openssl_decrypt(\n                $payload['value'], strtolower($this->cipher), $validKey, 0, $iv, $tag ?? ''\n            );\n        }\n\n        if (($decrypted ?? false) === false) {\n            throw new DecryptException('Could not decrypt the data.');\n        }\n\n        return $unserialize ? unserialize($decrypted) : $decrypted;\n    }\n\n    /**\n     * Decrypt the given string without unserialization.\n     *","sourceCodeStart":173,"sourceCodeEnd":209,"githubUrl":"https://github.com/laravel/framework/blob/e0f6eb3518ac29fbbca8529e97d0df7fc9f24481/src/Illuminate/Encryption/Encrypter.php#L173-L209","documentation":"During decryption, Encrypter iterates over the current and any previous keys, recomputing the MAC for each; if shouldValidateMac() is true and no key produced a matching MAC ($validKey === null), it throws DecryptException('The MAC is invalid.'). This is the canonical 'wrong key' or 'tampered payload' failure — the payload parsed fine but its MAC does not validate against any available key.","triggerScenarios":"Calling Crypt::decrypt() on a ciphertext that was encrypted with a key no longer in APP_KEY/previous_keys; on a payload whose value/iv/tag was altered (tampering); after an APP_KEY rotation without listing the old key in previous_keys.","commonSituations":"Rotating APP_KEY and forgetting to register the old key via Encrypter::previousKeys() / the app.previous_keys config; copying encrypted cookies/sessions between environments with different keys; a user manually editing an encrypted cookie; cross-environment data migration.","solutions":["Register the old key as a previous key so decryption can fall back: set app.previous_keys in config/app.php (Laravel) so both keys are tried.","If the key genuinely rotated and old data is unrecoverable, treat the payload as expired and re-issue (e.g. flush sessions, re-set encrypted cookies).","Verify the payload was not truncated or altered in transport (cookie size limits, proxy rewrites)."],"exampleFix":"// before\n// config/app.php: 'key' => env('APP_KEY'),\n\n// after (keep the old key available for decryption)\n// .env: APP_KEY=newkey\n//       APP_KEY_OLD=oldkey\n// config/app.php:\n'key' => env('APP_KEY'),\n'previous_keys' => [\n    env('APP_KEY_OLD'),\n],","handlingStrategy":"try-catch","validationCode":"// register previous keys so MAC validation can fall back\n// config/app.php\n'key' => env('APP_KEY'),\n'previous_keys' => array_filter([\n    env('APP_KEY_OLD'),\n]),","typeGuard":null,"tryCatchPattern":"use Illuminate\\Contracts\\Encryption\\DecryptException;\n\ntry {\n    return Crypt::decrypt($payload);\n} catch (DecryptException $e) {\n    if (str_contains($e->getMessage(), 'MAC is invalid')) {\n        // key rotation scenario — invalidate the session/data and re-issue\n        return null;\n    }\n    throw $e;\n}","preventionTips":["On APP_KEY rotation, keep the old key in app.previous_keys until all old ciphertexts are re-encrypted.","Never share encrypted cookies/sessions across environments with different APP_KEY values.","Treat a sudden spike of MAC-invalid errors as a key mismatch signal."],"tags":["encryption","security","decryption","app-key","key-rotation","mac"],"backgroundTag":null,"analyzedSha":"e0f6eb3518ac29fbbca8529e97d0df7fc9f24481","analyzedAt":"2026-08-11T20:52:37.562Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}