Muhammad Yasir Amin

Loading websiteโ€ฆ

More from Muhammad Yasir Amin

Build Along With Me

Practical walkthroughs on Laravel, React, APIs and deployment workflows.

Subscribe on YouTube

How to Generate an App Key in Laravel 13 with php artisan key:generate

๐Ÿ› ๏ธ Laravel Tutorials5 min read

How to Generate an App Key in Laravel 13 with php artisan key:generate

Muhammad Yasir Amin

Muhammad Yasir Amin

Senior Full Stack Engineerโ€ขNov 12, 2026
How to Generate an App Key in Laravel 13 with php artisan key:generate

To generate an app key in Laravel 13, run php artisan key:generate in the project root. The command creates a random 32-byte key, base64-encodes it and writes it to APP_KEY in your .env file. Laravel uses this key to encrypt cookies, sessions and anything you pass to Crypt or the encrypted cast, so every environment needs its own key and it must never be shared publicly.

New projects created with the Laravel installer or composer create-project already get a key. You run the command yourself after cloning a repository, copying .env.example, or setting up a new server.

Prerequisites

  • Laravel 13 with PHP 8.3 or newer.
  • A .env file in the project root (copy it from .env.example if it is missing).
  • Write access to .env for the user running Artisan.

Step 1: Create the .env file and generate the key

Code
cp .env.example .env
php artisan key:generate

Artisan prints a confirmation and .env now contains a line like this (yours will differ):

Code
APP_KEY=base64:REPLACE_WITH_YOUR_OWN_GENERATED_VALUE=

If your configuration is cached, clear it so Laravel reads the new value: php artisan config:clear.

What does APP_KEY protect?

  • Cookies and sessions. Laravel encrypts every cookie, including the session cookie, with this key.
  • Encrypted data. Values stored with Crypt::encryptString() or an Eloquent encrypted cast.
  • Signed URLs. Temporary and signed routes are signed with the key, so changing it invalidates existing links.

It does not affect password hashes. Passwords are hashed with bcrypt or Argon2, which do not use APP_KEY, so users can still log in after a key change; they are only signed out of their current sessions.

Step 2: Use --show and --force where needed

The command has two options:

SQL
# Print a new key without touching .env
php artisan key:generate --show

# Allow the command to run when APP_ENV=production
php artisan key:generate --force

--show is useful when your production secrets live in a platform dashboard or a secrets manager rather than a .env file: generate the value locally and paste it into the platform. In production, Artisan asks for confirmation before overwriting the key; --force skips that prompt. Only use it when you really mean to replace a key, because the old one is gone once it is overwritten.

How do you fix "No application encryption key has been specified"?

Laravel throws this error when APP_KEY is empty at runtime. Check these in order:

  1. .env exists in the project root and contains a non-empty APP_KEY.
  2. The config cache is not stale. Run php artisan config:clear, then php artisan config:cache again on production.
  3. In Docker or a platform, the variable is passed to the container or app. A key in your local .env does not reach a container unless you mount the file or set the environment variable.
  4. The value keeps its base64: prefix. Without it, Laravel treats the string as a raw key of the wrong length.

Step 3: Rotate the key without logging everyone out

If a key leaks, for example in a public repository, replace it immediately. Laravel supports graceful rotation through APP_PREVIOUS_KEYS. Laravel encrypts with the current key, and when decryption fails it tries each previous key in turn.

Code
php artisan key:generate --show

Put the new value in APP_KEY and move the old one into APP_PREVIOUS_KEYS:

Code
APP_KEY=base64:NEW_KEY_VALUE=
APP_PREVIOUS_KEYS=base64:OLD_KEY_VALUE=

Deploy and rebuild the config cache. Existing sessions and encrypted columns keep working. If you want to stop depending on the old key completely, re-encrypt stored data with a short script and then remove it from APP_PREVIOUS_KEYS:

JavaScript
<?php

use App\Models\Integration;
use Illuminate\Support\Facades\Crypt;
use Illuminate\Support\Facades\DB;

// Reading the cast attribute decrypts with whichever key works.
// Writing through the query builder stores a fresh value encrypted with the current key.
Integration::query()->chunkById(200, function ($integrations) {
    foreach ($integrations as $integration) {
        DB::table('integrations')
            ->where('id', $integration->id)
            ->update(['api_token' => Crypt::encryptString($integration->api_token)]);
    }
});

This example assumes api_token uses the encrypted cast, which stores values with encryptString. Reassigning the same value on the model and calling save() would not work: Eloquent compares the decrypted values, sees no change and skips the update. Writing through the query builder avoids that. Back up the table first and run it in a maintenance window if the table is large.

When a key has leaked, rotating it is not the whole fix: also rotate any secrets that were encrypted with it, because whoever has the old key can decrypt old copies of that data.

Common mistakes

  • Committing .env. Keep it in .gitignore. Commit only .env.example with an empty APP_KEY.
  • Sharing one key across environments. Local, staging and production should each have their own key.
  • Regenerating the key on every deploy. Some deploy scripts run key:generate --force each time, which logs everyone out and breaks encrypted data. Generate once per environment.
  • Several servers with different keys. Behind a load balancer, all app servers must share the same key or sessions fail randomly.

How do you verify it works?

PHP
php artisan tinker
>>> config('app.key') !== null
>>> Crypt::decryptString(Crypt::encryptString('hello'))

The second line should return hello. In the browser, log in, refresh a few pages and confirm the session persists.

FAQ

Is APP_KEY used for password hashing?

No. Password hashes are independent of the key, so changing it does not invalidate passwords.

Can I write my own key by hand?

Do not. Use key:generate, which uses a cryptographically secure random generator and the correct length for the cipher.

Which cipher does Laravel use?

The default is AES-256-CBC, set by cipher in config/app.php. Values are also signed with a MAC so tampering is detected.

References

Article Index & Topic Tags
LaravelSecurityArtisanEncryption

YouTube Channel

Build Along With Me

Practical walkthroughs on Laravel, React, APIs and deployment workflows.

Muhammad Yasir Amin
Available for Contracts
Author & Solutions Architect

Senior Full Stack Engineer

Independent Senior Full Stack Engineer working on Laravel, React and Next.js applications, APIs and delivery workflows.

Laravel & PHP ApplicationsReact & Next.js InterfacesREST APIs & IntegrationsDatabase Queries & DebuggingDocker Development WorkflowsClear Scope & Handover
Discuss Your Next Step

What Does Your Application Need Next?

Share your current system, the problem you want to solve and what a useful result looks like. We can identify the right starting point and agree on a practical scope.

Technical Audit

Find the Next Useful Fix

Application Development

Scoped, Reviewable Milestones

Ongoing Support

Agreed Capacity and Priorities

Share your goals, current stack and requirements before the call.